Merge pull request #1862 from messense/feature/fix-nightly-06-28

Fix compilation on rustc 1.20.0-nightly (69c65d296 2017-06-28)
This commit is contained in:
Oliver Schneider 2017-06-29 16:54:04 +02:00 committed by GitHub
commit 86b1c93940
23 changed files with 106 additions and 96 deletions

View File

@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file.
* Rewrite of the `doc_markdown` lint.
* Deprecated [`range_step_by_zero`]
* New lint: [`iterator_step_by_zero`]
* New lint: [`needless_borrowed_reference`]
* Update to *rustc 1.20.0-nightly (69c65d296 2017-06-28)*
## 0.0.140 - 2017-06-16
* Update to *rustc 1.19.0-nightly (258ae6dd9 2017-06-15)*

View File

@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.0.140"
version = "0.0.141"
authors = [
"Manish Goregaokar <manishsmail@gmail.com>",
"Andre Bogus <bogusandre@gmail.com>",
@ -31,7 +31,7 @@ test = false
[dependencies]
# begin automatic update
clippy_lints = { version = "0.0.140", path = "clippy_lints" }
clippy_lints = { version = "0.0.141", path = "clippy_lints" }
# end automatic update
cargo_metadata = "0.2"

View File

@ -1,7 +1,7 @@
[package]
name = "clippy_lints"
# begin automatic update
version = "0.0.140"
version = "0.0.141"
# end automatic update
authors = [
"Manish Goregaokar <manishsmail@gmail.com>",

View File

@ -136,9 +136,11 @@ impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> {
walk_expr(self, e);
let ty = self.cx.tables.node_id_to_type(callee.id);
match ty.sty {
ty::TyFnDef(_, _, ty) |
ty::TyFnPtr(ty) if ty.skip_binder().output().sty == ty::TyNever => {
self.divergence += 1;
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
let sig = ty.fn_sig(self.cx.tcx);
if sig.skip_binder().output().sty == ty::TyNever {
self.divergence += 1;
}
},
_ => (),
}

View File

@ -62,7 +62,7 @@ struct Parser<'a> {
impl<'a> Parser<'a> {
fn new(parser: pulldown_cmark::Parser<'a>) -> Parser<'a> {
Self { parser }
Self { parser: parser }
}
}
@ -89,10 +89,7 @@ pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<(
let doc = &comment[prefix.len()..];
let mut doc = doc.to_owned();
doc.push('\n');
return (
doc.to_owned(),
vec![(doc.len(), Span { lo: span.lo + BytePos(prefix.len() as u32), ..span })]
);
return (doc.to_owned(), vec![(doc.len(), Span { lo: span.lo + BytePos(prefix.len() as u32), ..span })]);
}
}
@ -105,7 +102,7 @@ pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<(
debug_assert_eq!(offset as u32 as usize, offset);
// +1 for the newline
sizes.push((line.len()+1, Span { lo: span.lo + BytePos(offset as u32), ..span }));
sizes.push((line.len() + 1, Span { lo: span.lo + BytePos(offset as u32), ..span }));
}
return (doc.to_string(), sizes);
@ -154,7 +151,7 @@ pub fn check_attrs<'a>(cx: &EarlyContext, valid_idents: &[String], attrs: &'a [a
let mut x = x.into_owned();
x.push_str(&y);
Ok((x_offset, Text(x.into())))
}
},
(x, y) => Err(((x_offset, x), (y_offset, y))),
}
});
@ -162,7 +159,7 @@ pub fn check_attrs<'a>(cx: &EarlyContext, valid_idents: &[String], attrs: &'a [a
}
}
fn check_doc<'a, Events: Iterator<Item=(usize, pulldown_cmark::Event<'a>)>>(
fn check_doc<'a, Events: Iterator<Item = (usize, pulldown_cmark::Event<'a>)>>(
cx: &EarlyContext,
valid_idents: &[String],
docs: Events,
@ -175,26 +172,27 @@ fn check_doc<'a, Events: Iterator<Item=(usize, pulldown_cmark::Event<'a>)>>(
for (offset, event) in docs {
match event {
Start(CodeBlock(_)) | Start(Code) => in_code = true,
End(CodeBlock(_)) | End(Code) => in_code = false,
Start(CodeBlock(_)) |
Start(Code) => in_code = true,
End(CodeBlock(_)) |
End(Code) => in_code = false,
Start(_tag) | End(_tag) => (), // We don't care about other tags
Html(_html) | InlineHtml(_html) => (), // HTML is weird, just ignore it
Html(_html) |
InlineHtml(_html) => (), // HTML is weird, just ignore it
SoftBreak => (),
HardBreak => (),
FootnoteReference(text) | Text(text) => {
FootnoteReference(text) |
Text(text) => {
if !in_code {
let index = match spans.binary_search_by(|c| c.0.cmp(&offset)) {
Ok(o) => o,
Err(e) => e-1,
Err(e) => e - 1,
};
let (begin, span) = spans[index];
// Adjust for the begining of the current `Event`
let span = Span {
lo: span.lo + BytePos::from_usize(offset - begin),
..span
};
let span = Span { lo: span.lo + BytePos::from_usize(offset - begin), ..span };
check_text(cx, valid_idents, &text, span);
}

View File

@ -64,10 +64,9 @@ fn check_closure(cx: &LateContext, expr: &Expr) {
let fn_ty = cx.tables.expr_ty(caller);
match fn_ty.sty {
// Is it an unsafe function? They don't implement the closure traits
ty::TyFnDef(_, _, fn_ty) |
ty::TyFnPtr(fn_ty) => {
if fn_ty.skip_binder().unsafety == Unsafety::Unsafe ||
fn_ty.skip_binder().output().sty == ty::TyNever {
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
let sig = fn_ty.fn_sig(cx.tcx);
if sig.skip_binder().unsafety == Unsafety::Unsafe || sig.skip_binder().output().sty == ty::TyNever {
return;
}
},

View File

@ -126,10 +126,11 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
match e.node {
ExprAgain(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e),
ExprCall(ref func, _) => {
match self.cx.tables.expr_ty(func).sty {
ty::TyFnDef(_, _, fn_ty) |
ty::TyFnPtr(fn_ty) => {
if let ty::TyNever = self.cx.tcx.erase_late_bound_regions(&fn_ty).output().sty {
let typ = self.cx.tables.expr_ty(func);
match typ.sty {
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
let sig = typ.fn_sig(self.cx.tcx);
if let ty::TyNever = self.cx.tcx.erase_late_bound_regions(&sig).output().sty {
self.report_diverging_sub_expr(e);
}
},

View File

@ -176,7 +176,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
hir::ExprCall(ref f, ref args) => {
let ty = self.cx.tables.expr_ty(f);
if type_is_unsafe_function(ty) {
if type_is_unsafe_function(self.cx, ty) {
for arg in args {
self.check_arg(arg);
}
@ -186,7 +186,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
let def_id = self.cx.tables.type_dependent_defs[&expr.id].def_id();
let base_type = self.cx.tcx.type_of(def_id);
if type_is_unsafe_function(base_type) {
if type_is_unsafe_function(self.cx, base_type) {
for arg in args {
self.check_arg(arg);
}

View File

@ -94,8 +94,7 @@ fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItemRef]
has_self &&
{
let did = cx.tcx.hir.local_def_id(item.id.node_id);
let impl_ty = cx.tcx.type_of(did);
impl_ty.fn_sig().inputs().skip_binder().len() == 1
cx.tcx.fn_sig(did).inputs().skip_binder().len() == 1
}
} else {
false
@ -121,8 +120,7 @@ fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) {
has_self &&
{
let did = cx.tcx.hir.local_def_id(item.id.node_id);
let impl_ty = cx.tcx.type_of(did);
impl_ty.fn_sig().inputs().skip_binder().len() == 1
cx.tcx.fn_sig(did).inputs().skip_binder().len() == 1
}
} else {
false
@ -171,7 +169,10 @@ fn check_cmp(cx: &LateContext, span: Span, left: &Expr, right: &Expr, op: &str)
fn check_len_zero(cx: &LateContext, span: Span, name: Name, args: &[Expr], lit: &Lit, op: &str) {
if let Spanned { node: LitKind::Int(0, _), .. } = *lit {
if name == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) {
span_lint_and_sugg(cx, LEN_ZERO, span, "length comparison to zero",
span_lint_and_sugg(cx,
LEN_ZERO,
span,
"length comparison to zero",
"using `is_empty` is more concise:",
format!("{}{}.is_empty()", op, snippet(cx, args[0].span, "_")));
}
@ -184,7 +185,7 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool {
fn is_is_empty(cx: &LateContext, item: &ty::AssociatedItem) -> bool {
if let ty::AssociatedKind::Method = item.kind {
if item.name == "is_empty" {
let sig = cx.tcx.type_of(item.def_id).fn_sig();
let sig = cx.tcx.fn_sig(item.def_id);
let ty = sig.skip_binder();
ty.inputs().len() == 1
} else {

View File

@ -434,8 +434,8 @@ fn never_loop(block: &Block, id: &NodeId) -> bool {
}
fn contains_continue_block(block: &Block, dest: &NodeId) -> bool {
block.stmts.iter().any(|e| contains_continue_stmt(e, dest))
|| block.expr.as_ref().map_or(false, |e| contains_continue_expr(e, dest))
block.stmts.iter().any(|e| contains_continue_stmt(e, dest)) ||
block.expr.as_ref().map_or(false, |e| contains_continue_expr(e, dest))
}
fn contains_continue_stmt(stmt: &Stmt, dest: &NodeId) -> bool {
@ -449,7 +449,7 @@ fn contains_continue_stmt(stmt: &Stmt, dest: &NodeId) -> bool {
fn contains_continue_decl(decl: &Decl, dest: &NodeId) -> bool {
match decl.node {
DeclLocal(ref local) => local.init.as_ref().map_or(false, |e| contains_continue_expr(e, dest)),
_ => false
_ => false,
}
}
@ -466,14 +466,20 @@ fn contains_continue_expr(expr: &Expr, dest: &NodeId) -> bool {
ExprArray(ref es) |
ExprMethodCall(_, _, ref es) |
ExprTup(ref es) => es.iter().any(|e| contains_continue_expr(e, dest)),
ExprCall(ref e, ref es) => contains_continue_expr(e, dest) || es.iter().any(|e| contains_continue_expr(e, dest)),
ExprCall(ref e, ref es) => {
contains_continue_expr(e, dest) || es.iter().any(|e| contains_continue_expr(e, dest))
},
ExprBinary(_, ref e1, ref e2) |
ExprAssign(ref e1, ref e2) |
ExprAssignOp(_, ref e1, ref e2) |
ExprIndex(ref e1, ref e2) => [e1, e2].iter().any(|e| contains_continue_expr(e, dest)),
ExprIf(ref e, ref e2, ref e3) => [e, e2].iter().chain(e3.as_ref().iter()).any(|e| contains_continue_expr(e, dest)),
ExprIf(ref e, ref e2, ref e3) => {
[e, e2].iter().chain(e3.as_ref().iter()).any(|e| contains_continue_expr(e, dest))
},
ExprWhile(ref e, ref b, _) => contains_continue_expr(e, dest) || contains_continue_block(b, dest),
ExprMatch(ref e, ref arms, _) => contains_continue_expr(e, dest) || arms.iter().any(|a| contains_continue_expr(&a.body, dest)),
ExprMatch(ref e, ref arms, _) => {
contains_continue_expr(e, dest) || arms.iter().any(|a| contains_continue_expr(&a.body, dest))
},
ExprBlock(ref block) => contains_continue_block(block, dest),
ExprStruct(_, _, ref base) => base.as_ref().map_or(false, |e| contains_continue_expr(e, dest)),
ExprAgain(d) => d.target_id.opt_id().map_or(false, |id| id == *dest),
@ -482,8 +488,7 @@ fn contains_continue_expr(expr: &Expr, dest: &NodeId) -> bool {
}
fn loop_exit_block(block: &Block) -> bool {
block.stmts.iter().any(|e| loop_exit_stmt(e))
|| block.expr.as_ref().map_or(false, |e| loop_exit_expr(e))
block.stmts.iter().any(|e| loop_exit_stmt(e)) || block.expr.as_ref().map_or(false, |e| loop_exit_expr(e))
}
fn loop_exit_stmt(stmt: &Stmt) -> bool {
@ -497,7 +502,7 @@ fn loop_exit_stmt(stmt: &Stmt) -> bool {
fn loop_exit_decl(decl: &Decl) -> bool {
match decl.node {
DeclLocal(ref local) => local.init.as_ref().map_or(false, |e| loop_exit_expr(e)),
_ => false
_ => false,
}
}
@ -519,13 +524,13 @@ fn loop_exit_expr(expr: &Expr) -> bool {
ExprAssign(ref e1, ref e2) |
ExprAssignOp(_, ref e1, ref e2) |
ExprIndex(ref e1, ref e2) => [e1, e2].iter().any(|e| loop_exit_expr(e)),
ExprIf(ref e, ref e2, ref e3) => loop_exit_expr(e) || e3.as_ref().map_or(false, |e| loop_exit_expr(e)) && loop_exit_expr(e2),
ExprIf(ref e, ref e2, ref e3) => {
loop_exit_expr(e) || e3.as_ref().map_or(false, |e| loop_exit_expr(e)) && loop_exit_expr(e2)
},
ExprWhile(ref e, ref b, _) => loop_exit_expr(e) || loop_exit_block(b),
ExprMatch(ref e, ref arms, _) => loop_exit_expr(e) || arms.iter().all(|a| loop_exit_expr(&a.body)),
ExprBlock(ref b) => loop_exit_block(b),
ExprBreak(_, _) |
ExprAgain(_) |
ExprRet(_) => true,
ExprBreak(_, _) | ExprAgain(_) | ExprRet(_) => true,
_ => false,
}
}
@ -741,7 +746,7 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
let substs = cx.tables.node_substs(arg.id);
let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs);
let fn_arg_tys = method_type.fn_sig().inputs();
let fn_arg_tys = method_type.fn_sig(cx.tcx).inputs();
assert_eq!(fn_arg_tys.skip_binder().len(), 1);
if fn_arg_tys.skip_binder()[0].is_region_ptr() {
lint_iter_method(cx, args, arg, &method_name);

View File

@ -2,8 +2,8 @@ use rustc::lint::*;
use rustc::hir::*;
use rustc::ty;
use syntax::ast;
use utils::{is_adjusted, match_path, match_trait_method, match_type, remove_blocks, paths, snippet,
span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, iter_input_pats};
use utils::{is_adjusted, match_path, match_trait_method, match_type, remove_blocks, paths, snippet, span_help_and_lint,
walk_ptrs_ty, walk_ptrs_ty_depth, iter_input_pats};
/// **What it does:** Checks for mapping `clone()` over an iterator.
///

View File

@ -9,8 +9,8 @@ use std::collections::Bound;
use syntax::ast::LitKind;
use syntax::codemap::Span;
use utils::paths;
use utils::{match_type, snippet, span_note_and_lint, span_lint_and_then, span_lint_and_sugg, in_external_macro, expr_block, walk_ptrs_ty,
is_expn_of, remove_blocks};
use utils::{match_type, snippet, span_note_and_lint, span_lint_and_then, span_lint_and_sugg, in_external_macro,
expr_block, walk_ptrs_ty, is_expn_of, remove_blocks};
use utils::sugg::Sugg;
/// **What it does:** Checks for matches with a single arm where an `if let`

View File

@ -8,9 +8,9 @@ use std::borrow::Cow;
use std::fmt;
use syntax::codemap::Span;
use utils::{get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, match_path, match_trait_method,
match_type, method_chain_args, return_ty, same_tys, snippet, span_lint, span_lint_and_then, span_lint_and_sugg,
span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, last_path_segment, single_segment_path,
match_def_path, is_self, is_self_ty, iter_input_pats, match_path_old};
match_type, method_chain_args, return_ty, same_tys, snippet, span_lint, span_lint_and_then,
span_lint_and_sugg, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, last_path_segment,
single_segment_path, match_def_path, is_self, is_self_ty, iter_input_pats, match_path_old};
use utils::paths;
use utils::sugg;
@ -859,7 +859,10 @@ fn lint_string_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) {
return;
};
span_lint_and_sugg(cx, STRING_EXTEND_CHARS, expr.span, "calling `.extend(_.chars())`",
span_lint_and_sugg(cx,
STRING_EXTEND_CHARS,
expr.span,
"calling `.extend(_.chars())`",
"try this",
format!("{}.push_str({}{})",
snippet(cx, args[0].span, "_"),

View File

@ -55,11 +55,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed {
}
}
fn check_arguments(cx: &LateContext, arguments: &[Expr], type_definition: Ty, name: &str) {
fn check_arguments<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arguments: &[Expr], type_definition: Ty<'tcx>, name: &str) {
match type_definition.sty {
ty::TyFnDef(_, _, fn_type) |
ty::TyFnPtr(fn_type) => {
let parameters = fn_type.skip_binder().inputs();
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();
for (argument, parameter) in arguments.iter().zip(parameters.iter()) {
match parameter.sty {
ty::TyRef(_, ty::TypeAndMut { mutbl: MutImmutable, .. }) |

View File

@ -9,7 +9,8 @@ use utils::{span_lint, in_macro};
/// **What it does:** Checks for useless borrowed references.
///
/// **Why is this bad?** It is completely useless and make the code look more complex than it actually is.
/// **Why is this bad?** It is completely useless and make the code look more complex than it
/// actually is.
///
/// **Known problems:** None.
///
@ -18,7 +19,8 @@ use utils::{span_lint, in_macro};
/// let mut v = Vec::<String>::new();
/// let _ = v.iter_mut().filter(|&ref a| a.is_empty());
/// ```
/// This clojure takes a reference on something that has been matched as a reference and de-referenced.
/// This clojure takes a reference on something that has been matched as a reference and
/// de-referenced.
/// As such, it could just be |a| a.is_empty()
declare_lint! {
pub NEEDLESS_BORROWED_REFERENCE,
@ -55,4 +57,3 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrowedRef {
}}
}
}

View File

@ -95,7 +95,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
ctx
};
let fn_sig = cx.tcx.type_of(fn_def_id).fn_sig();
let fn_sig = cx.tcx.fn_sig(fn_def_id);
let fn_sig = cx.tcx.erase_late_bound_regions(&fn_sig);
for ((input, &ty), arg) in decl.inputs.iter().zip(fn_sig.inputs()).zip(&body.arguments) {

View File

@ -36,11 +36,14 @@ impl LintPass for Precedence {
impl EarlyLintPass for Precedence {
fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.node {
let span_sugg =
|expr: &Expr, sugg| {
span_lint_and_sugg(cx, PRECEDENCE, expr.span, "operator precedence can trip the unwary",
"consider parenthesizing your expression", sugg);
};
let span_sugg = |expr: &Expr, sugg| {
span_lint_and_sugg(cx,
PRECEDENCE,
expr.span,
"operator precedence can trip the unwary",
"consider parenthesizing your expression",
sugg);
};
if !is_bit_op(op) {
return;

View File

@ -113,7 +113,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PointerPass {
fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId) {
let fn_def_id = cx.tcx.hir.local_def_id(fn_id);
let sig = cx.tcx.type_of(fn_def_id).fn_sig();
let sig = cx.tcx.fn_sig(fn_def_id);
let fn_ty = sig.skip_binder();
for (arg, ty) in decl.inputs.iter().zip(fn_ty.inputs()) {

View File

@ -58,12 +58,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StepByZero {
use rustc_const_math::ConstInt::Usize;
if let Some((Constant::Int(Usize(us)), _)) = constant(cx, &args[1]) {
if us.as_u64(cx.sess().target.uint_type) == 0 {
span_lint(
cx,
ITERATOR_STEP_BY_ZERO,
expr.span,
"Iterator::step_by(0) will panic at runtime",
);
span_lint(cx,
ITERATOR_STEP_BY_ZERO,
expr.span,
"Iterator::step_by(0) will panic at runtime");
}
}
} else if name == "zip" && args.len() == 2 {
@ -100,9 +98,5 @@ fn has_step_by(cx: &LateContext, expr: &Expr) -> bool {
// can't be called on a borrowed range.
let ty = cx.tables.expr_ty_adjusted(expr);
get_trait_def_id(cx, &paths::ITERATOR)
.map_or(
false,
|iterator_trait| implements_trait(cx, ty, iterator_trait, &[])
)
get_trait_def_id(cx, &paths::ITERATOR).map_or(false, |iterator_trait| implements_trait(cx, ty, iterator_trait, &[]))
}

View File

@ -40,8 +40,12 @@ impl EarlyLintPass for Pass {
fn check_expr(&mut self, cx: &EarlyContext, e: &Expr) {
if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.node {
if let ExprKind::AddrOf(_, ref addrof_target) = without_parens(deref_target).node {
span_lint_and_sugg(cx, DEREF_ADDROF, e.span, "immediately dereferencing a reference",
"try this", format!("{}", snippet(cx, addrof_target.span, "_")));
span_lint_and_sugg(cx,
DEREF_ADDROF,
e.span,
"immediately dereferencing a reference",
"try this",
format!("{}", snippet(cx, addrof_target.span, "_")));
}
}
}

View File

@ -3,8 +3,7 @@ use syntax::ast;
use syntax::codemap::{Span, Spanned};
use syntax::visit::FnKind;
use utils::{span_note_and_lint, span_lint_and_then, snippet_opt, match_path_ast, in_macro,
in_external_macro};
use utils::{span_note_and_lint, span_lint_and_then, snippet_opt, match_path_ast, in_macro, in_external_macro};
/// **What it does:** Checks for return statements at the end of a block.
///

View File

@ -8,8 +8,8 @@ use std::cmp::Ordering;
use syntax::ast::{IntTy, UintTy, FloatTy};
use syntax::attr::IntType;
use syntax::codemap::Span;
use utils::{comparisons, higher, in_external_macro, in_macro, match_def_path, snippet, span_help_and_lint, span_lint, span_lint_and_sugg,
opt_def_id, last_path_segment, type_size};
use utils::{comparisons, higher, in_external_macro, in_macro, match_def_path, snippet, span_help_and_lint, span_lint,
span_lint_and_sugg, opt_def_id, last_path_segment, type_size};
use utils::paths;
/// Handles all the linting of funky types

View File

@ -764,7 +764,7 @@ pub fn camel_case_from(s: &str) -> usize {
/// Convenience function to get the return type of a function
pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: NodeId) -> Ty<'tcx> {
let fn_def_id = cx.tcx.hir.local_def_id(fn_item);
let ret_ty = cx.tcx.type_of(fn_def_id).fn_sig().output();
let ret_ty = cx.tcx.fn_sig(fn_def_id).output();
cx.tcx.erase_late_bound_regions(&ret_ty)
}
@ -776,10 +776,9 @@ pub fn same_tys<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
}
/// Return whether the given type is an `unsafe` function.
pub fn type_is_unsafe_function(ty: Ty) -> bool {
pub fn type_is_unsafe_function<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
match ty.sty {
ty::TyFnDef(_, _, f) |
ty::TyFnPtr(f) => f.unsafety() == Unsafety::Unsafe,
ty::TyFnDef(..) | ty::TyFnPtr(_) => ty.fn_sig(cx.tcx).unsafety() == Unsafety::Unsafe,
_ => false,
}
}