mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-15 01:17:16 +00:00
Simplify lifetime-differences-only detection
Now instead of reinventing the wheel with differ_only_in_lifetimes(), we use TyCtxt's erase_regions()
This commit is contained in:
parent
8134863c13
commit
9118cd633e
1 changed files with 2 additions and 45 deletions
|
@ -1,8 +1,7 @@
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::ty::{self, Ty, walk::TypeWalker};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::mem;
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use utils::{last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_then};
|
use utils::{last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_then};
|
||||||
use utils::{opt_def_id, sugg};
|
use utils::{opt_def_id, sugg};
|
||||||
|
@ -364,7 +363,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
if !differ_only_in_lifetime_params(from_ty, to_ty) {
|
if cx.tcx.erase_regions(&from_ty) != cx.tcx.erase_regions(&to_ty) {
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
TRANSMUTE_PTR_TO_PTR,
|
TRANSMUTE_PTR_TO_PTR,
|
||||||
|
@ -448,48 +447,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if `type1` and `type2` are the same type except for their lifetime parameters
|
|
||||||
fn differ_only_in_lifetime_params(type1: Ty, type2: Ty) -> bool {
|
|
||||||
use rustc::ty::TypeVariants::*;
|
|
||||||
if TypeWalker::new(type1).count() != TypeWalker::new(type2).count() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TypeWalker::new(type1)
|
|
||||||
.zip(TypeWalker::new(type2))
|
|
||||||
.all(|(t1, t2)| {
|
|
||||||
match (&t1.sty, &t2.sty) {
|
|
||||||
// types with generic parameters which can contain lifetimes
|
|
||||||
(TyAdt(_, sub1), TyAdt(_, sub2))
|
|
||||||
| (TyFnDef(_, sub1), TyFnDef(_, sub2))
|
|
||||||
| (TyAnon(_, sub1), TyAnon(_, sub2))
|
|
||||||
=> {
|
|
||||||
// Iterate over generic parameters, which are either Lifetimes or Types.
|
|
||||||
// Here we only need to check that they are the same type of thing, because
|
|
||||||
// if they are both Lifetimes then we don't care about their equality, and if
|
|
||||||
// they are both Types, we will check their equality later in the type walk.
|
|
||||||
sub1.iter().count() == sub2.iter().count()
|
|
||||||
&& sub1.iter().zip(sub2.iter()).all(|(k1, k2)| {
|
|
||||||
mem::discriminant(&k1.unpack()) == mem::discriminant(&k2.unpack())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// types without subtypes: check that the types are equal
|
|
||||||
(TyBool, TyBool)
|
|
||||||
| (TyChar, TyChar)
|
|
||||||
| (TyInt(_), TyInt(_))
|
|
||||||
| (TyUint(_), TyUint(_))
|
|
||||||
| (TyFloat(_), TyFloat(_))
|
|
||||||
| (TyForeign(_), TyForeign(_))
|
|
||||||
| (TyStr, TyStr)
|
|
||||||
| (TyNever, TyNever)
|
|
||||||
| (TyInfer(_), TyInfer(_))
|
|
||||||
=> t1.sty == t2.sty,
|
|
||||||
// types with subtypes: return true for now if they are the same sort of type.
|
|
||||||
// we will check their subtypes later
|
|
||||||
(sty1, sty2) => mem::discriminant(sty1) == mem::discriminant(sty2)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the snippet of `Bar` in `…::transmute<Foo, &Bar>`. If that snippet is
|
/// Get the snippet of `Bar` in `…::transmute<Foo, &Bar>`. If that snippet is
|
||||||
/// not available , use
|
/// not available , use
|
||||||
/// the type's `ToString` implementation. In weird cases it could lead to types
|
/// the type's `ToString` implementation. In weird cases it could lead to types
|
||||||
|
|
Loading…
Reference in a new issue