Partially apply rustfmt
This commit is contained in:
parent
0c726e8077
commit
c0d2fdc723
12 changed files with 92 additions and 85 deletions
|
@ -60,10 +60,10 @@ impl LateLintPass for AttrPass {
|
||||||
check_semver(cx, item.span, lit);
|
check_semver(cx, item.span, lit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||||
if is_relevant_item(item) {
|
if is_relevant_item(item) {
|
||||||
check_attrs(cx, item.span, &item.name, &item.attrs)
|
check_attrs(cx, item.span, &item.name, &item.attrs)
|
||||||
|
@ -164,7 +164,7 @@ fn check_semver(cx: &LateContext, span: Span, lit: &Lit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
DEPRECATED_SEMVER,
|
DEPRECATED_SEMVER,
|
||||||
span,
|
span,
|
||||||
"the since field must contain a semver-compliant version");
|
"the since field must contain a semver-compliant version");
|
||||||
|
|
|
@ -151,7 +151,6 @@ fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_, mask_value:
|
||||||
} else if mask_value == 0 {
|
} else if mask_value == 0 {
|
||||||
span_lint(cx, BAD_BIT_MASK, *span, "&-masking with zero");
|
span_lint(cx, BAD_BIT_MASK, *span, "&-masking with zero");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
BiBitOr => {
|
BiBitOr => {
|
||||||
if mask_value | cmp_value != cmp_value {
|
if mask_value | cmp_value != cmp_value {
|
||||||
|
|
|
@ -158,15 +158,13 @@ fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, trait_ref:
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
span_lint_and_then(
|
span_lint_and_then(cx,
|
||||||
cx, DERIVE_HASH_NOT_EQ, span,
|
DERIVE_HASH_NOT_EQ,
|
||||||
"you are implementing `Clone` explicitly on a `Copy` type",
|
span,
|
||||||
|db| {
|
"you are implementing `Clone` explicitly on a `Copy` type",
|
||||||
db.span_note(
|
|db| {
|
||||||
span,
|
db.span_note(span, "consider deriving `Clone` or removing `Copy`");
|
||||||
"consider deriving `Clone` or removing `Copy`"
|
});
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +172,7 @@ fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, trait_ref:
|
||||||
fn is_automatically_derived(attr: &Attribute) -> bool {
|
fn is_automatically_derived(attr: &Attribute) -> bool {
|
||||||
if let MetaItem_::MetaWord(ref word) = attr.node.value.node {
|
if let MetaItem_::MetaWord(ref word) = attr.node.value.node {
|
||||||
word == &"automatically_derived"
|
word == &"automatically_derived"
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ declare_lint!(pub BOXED_LOCAL, Warn, "using Box<T> where unnecessary");
|
||||||
fn is_non_trait_box(ty: ty::Ty) -> bool {
|
fn is_non_trait_box(ty: ty::Ty) -> bool {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyBox(ref inner) => !inner.is_trait(),
|
ty::TyBox(ref inner) => !inner.is_trait(),
|
||||||
_ => false
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,10 @@ impl EarlyLintPass for ItemsAfterStatemets {
|
||||||
if in_macro(cx, it.span) {
|
if in_macro(cx, it.span) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cx.struct_span_lint(ITEMS_AFTER_STATEMENTS, it.span,
|
cx.struct_span_lint(ITEMS_AFTER_STATEMENTS,
|
||||||
"adding items after statements is confusing, since items exist from the start of the scope")
|
it.span,
|
||||||
|
"adding items after statements is confusing, since items exist from the \
|
||||||
|
start of the scope")
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,9 +68,13 @@ enum RefLt {
|
||||||
|
|
||||||
fn bound_lifetimes(bound: &TyParamBound) -> Option<HirVec<&Lifetime>> {
|
fn bound_lifetimes(bound: &TyParamBound) -> Option<HirVec<&Lifetime>> {
|
||||||
if let TraitTyParamBound(ref trait_ref, _) = *bound {
|
if let TraitTyParamBound(ref trait_ref, _) = *bound {
|
||||||
let lt = trait_ref.trait_ref.path.segments
|
let lt = trait_ref.trait_ref
|
||||||
.last().expect("a path must have at least one segment")
|
.path
|
||||||
.parameters.lifetimes();
|
.segments
|
||||||
|
.last()
|
||||||
|
.expect("a path must have at least one segment")
|
||||||
|
.parameters
|
||||||
|
.lifetimes();
|
||||||
|
|
||||||
Some(lt)
|
Some(lt)
|
||||||
} else {
|
} else {
|
||||||
|
@ -83,10 +87,9 @@ fn check_fn_inner(cx: &LateContext, decl: &FnDecl, slf: Option<&ExplicitSelf>, g
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bounds_lts =
|
let bounds_lts = generics.ty_params
|
||||||
generics.ty_params
|
.iter()
|
||||||
.iter()
|
.flat_map(|ref typ| typ.bounds.iter().filter_map(bound_lifetimes).flat_map(|lts| lts));
|
||||||
.flat_map(|ref typ| typ.bounds.iter().filter_map(bound_lifetimes).flat_map(|lts| lts));
|
|
||||||
|
|
||||||
if could_use_elision(cx, decl, slf, &generics.lifetimes, bounds_lts) {
|
if could_use_elision(cx, decl, slf, &generics.lifetimes, bounds_lts) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
|
@ -97,10 +100,9 @@ fn check_fn_inner(cx: &LateContext, decl: &FnDecl, slf: Option<&ExplicitSelf>, g
|
||||||
report_extra_lifetimes(cx, decl, &generics, slf);
|
report_extra_lifetimes(cx, decl, &generics, slf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn could_use_elision<'a, T: Iterator<Item=&'a Lifetime>>(
|
fn could_use_elision<'a, T: Iterator<Item = &'a Lifetime>>(cx: &LateContext, func: &FnDecl, slf: Option<&ExplicitSelf>,
|
||||||
cx: &LateContext, func: &FnDecl, slf: Option<&ExplicitSelf>,
|
named_lts: &[LifetimeDef], bounds_lts: T)
|
||||||
named_lts: &[LifetimeDef], bounds_lts: T
|
-> bool {
|
||||||
) -> bool {
|
|
||||||
// There are two scenarios where elision works:
|
// There are two scenarios where elision works:
|
||||||
// * no output references, all input references have different LT
|
// * no output references, all input references have different LT
|
||||||
// * output references, exactly one input reference with same LT
|
// * output references, exactly one input reference with same LT
|
||||||
|
@ -185,7 +187,7 @@ fn allowed_lts_from(named_lts: &[LifetimeDef]) -> HashSet<RefLt> {
|
||||||
allowed_lts
|
allowed_lts
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lts_from_bounds<'a, T: Iterator<Item=&'a Lifetime>>(mut vec: Vec<RefLt>, bounds_lts: T) -> Vec<RefLt> {
|
fn lts_from_bounds<'a, T: Iterator<Item = &'a Lifetime>>(mut vec: Vec<RefLt>, bounds_lts: T) -> Vec<RefLt> {
|
||||||
for lt in bounds_lts {
|
for lt in bounds_lts {
|
||||||
if lt.name.as_str() != "'static" {
|
if lt.name.as_str() != "'static" {
|
||||||
vec.push(RefLt::Named(lt.name));
|
vec.push(RefLt::Named(lt.name));
|
||||||
|
@ -332,8 +334,7 @@ impl<'v> Visitor<'v> for LifetimeChecker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_extra_lifetimes(cx: &LateContext, func: &FnDecl,
|
fn report_extra_lifetimes(cx: &LateContext, func: &FnDecl, generics: &Generics, slf: Option<&ExplicitSelf>) {
|
||||||
generics: &Generics, slf: Option<&ExplicitSelf>) {
|
|
||||||
let hs = generics.lifetimes
|
let hs = generics.lifetimes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|lt| (lt.lifetime.name, lt.lifetime.span))
|
.map(|lt| (lt.lifetime.name, lt.lifetime.span))
|
||||||
|
|
|
@ -296,16 +296,14 @@ fn check_for_loop_range(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, ex
|
||||||
|
|
||||||
let skip: Cow<_> = if starts_at_zero {
|
let skip: Cow<_> = if starts_at_zero {
|
||||||
"".into()
|
"".into()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
format!(".skip({})", snippet(cx, l.span, "..")).into()
|
format!(".skip({})", snippet(cx, l.span, "..")).into()
|
||||||
};
|
};
|
||||||
|
|
||||||
let take: Cow<_> = if let Some(ref r) = *r {
|
let take: Cow<_> = if let Some(ref r) = *r {
|
||||||
if !is_len_call(&r, &indexed) {
|
if !is_len_call(&r, &indexed) {
|
||||||
format!(".take({})", snippet(cx, r.span, "..")).into()
|
format!(".take({})", snippet(cx, r.span, "..")).into()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
"".into()
|
"".into()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -327,8 +325,7 @@ fn check_for_loop_range(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, ex
|
||||||
} else {
|
} else {
|
||||||
let repl = if starts_at_zero && take.is_empty() {
|
let repl = if starts_at_zero && take.is_empty() {
|
||||||
format!("&{}", indexed)
|
format!("&{}", indexed)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
format!("{}.iter(){}{}", indexed, take, skip)
|
format!("{}.iter(){}{}", indexed, take, skip)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,7 @@ fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr:
|
||||||
},
|
},
|
||||||
PatEnum(ref path, None) => path.to_string(),
|
PatEnum(ref path, None) => path.to_string(),
|
||||||
PatIdent(BindByValue(MutImmutable), ident, None) => ident.node.to_string(),
|
PatIdent(BindByValue(MutImmutable), ident, None) => ident.node.to_string(),
|
||||||
_ => return
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
for &(ty_path, pat_path) in candidates {
|
for &(ty_path, pat_path) in candidates {
|
||||||
|
@ -206,15 +206,17 @@ fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr:
|
||||||
span_lint_and_then(cx,
|
span_lint_and_then(cx,
|
||||||
lint,
|
lint,
|
||||||
expr.span,
|
expr.span,
|
||||||
"you seem to be trying to use match for destructuring a single pattern. \
|
"you seem to be trying to use match for destructuring a single pattern. Consider \
|
||||||
Consider using `if let`", |db| {
|
using `if let`",
|
||||||
db.span_suggestion(expr.span, "try this",
|
|db| {
|
||||||
format!("if let {} = {} {}{}",
|
db.span_suggestion(expr.span,
|
||||||
snippet(cx, arms[0].pats[0].span, ".."),
|
"try this",
|
||||||
snippet(cx, ex.span, ".."),
|
format!("if let {} = {} {}{}",
|
||||||
expr_block(cx, &arms[0].body, None, ".."),
|
snippet(cx, arms[0].pats[0].span, ".."),
|
||||||
els_str));
|
snippet(cx, ex.span, ".."),
|
||||||
});
|
expr_block(cx, &arms[0].body, None, ".."),
|
||||||
|
els_str));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,12 +269,12 @@ fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
|
||||||
span_lint_and_then(cx,
|
span_lint_and_then(cx,
|
||||||
MATCH_BOOL,
|
MATCH_BOOL,
|
||||||
expr.span,
|
expr.span,
|
||||||
"you seem to be trying to match on a boolean expression. Consider using \
|
"you seem to be trying to match on a boolean expression. Consider using an if..else block:",
|
||||||
an if..else block:", move |db| {
|
move |db| {
|
||||||
if let Some(sugg) = sugg {
|
if let Some(sugg) = sugg {
|
||||||
db.span_suggestion(expr.span, "try this", sugg);
|
db.span_suggestion(expr.span, "try this", sugg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -349,16 +349,18 @@ fn lint_or_fun_call(cx: &LateContext, expr: &Expr, name: &str, args: &[P<Expr>])
|
||||||
|
|
||||||
if name == "unwrap_or" {
|
if name == "unwrap_or" {
|
||||||
if let ExprPath(_, ref path) = fun.node {
|
if let ExprPath(_, ref path) = fun.node {
|
||||||
let path : &str = &path.segments.last()
|
let path: &str = &path.segments
|
||||||
.expect("A path must have at least one segment")
|
.last()
|
||||||
.identifier.name.as_str();
|
.expect("A path must have at least one segment")
|
||||||
|
.identifier
|
||||||
|
.name
|
||||||
|
.as_str();
|
||||||
|
|
||||||
if ["default", "new"].contains(&path) {
|
if ["default", "new"].contains(&path) {
|
||||||
let arg_ty = cx.tcx.expr_ty(arg);
|
let arg_ty = cx.tcx.expr_ty(arg);
|
||||||
let default_trait_id = if let Some(default_trait_id) = get_trait_def_id(cx, &DEFAULT_TRAIT_PATH) {
|
let default_trait_id = if let Some(default_trait_id) = get_trait_def_id(cx, &DEFAULT_TRAIT_PATH) {
|
||||||
default_trait_id
|
default_trait_id
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -408,7 +410,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &Expr, name: &str, args: &[P<Expr>])
|
||||||
};
|
};
|
||||||
|
|
||||||
if !poss.contains(&name) {
|
if !poss.contains(&name) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sugg = match (fn_has_arguments, !or_has_args) {
|
let sugg = match (fn_has_arguments, !or_has_args) {
|
||||||
|
@ -444,17 +446,20 @@ fn lint_extend(cx: &LateContext, expr: &Expr, args: &MethodArgs) {
|
||||||
}
|
}
|
||||||
let arg_ty = cx.tcx.expr_ty(&args[1]);
|
let arg_ty = cx.tcx.expr_ty(&args[1]);
|
||||||
if let Some((span, r)) = derefs_to_slice(cx, &args[1], &arg_ty) {
|
if let Some((span, r)) = derefs_to_slice(cx, &args[1], &arg_ty) {
|
||||||
span_lint(cx, EXTEND_FROM_SLICE, expr.span,
|
span_lint(cx,
|
||||||
|
EXTEND_FROM_SLICE,
|
||||||
|
expr.span,
|
||||||
&format!("use of `extend` to extend a Vec by a slice"))
|
&format!("use of `extend` to extend a Vec by a slice"))
|
||||||
.span_suggestion(expr.span, "try this",
|
.span_suggestion(expr.span,
|
||||||
|
"try this",
|
||||||
format!("{}.extend_from_slice({}{})",
|
format!("{}.extend_from_slice({}{})",
|
||||||
snippet(cx, args[0].span, "_"),
|
snippet(cx, args[0].span, "_"),
|
||||||
r, snippet(cx, span, "_")));
|
r,
|
||||||
|
snippet(cx, span, "_")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derefs_to_slice(cx: &LateContext, expr: &Expr, ty: &ty::Ty)
|
fn derefs_to_slice(cx: &LateContext, expr: &Expr, ty: &ty::Ty) -> Option<(Span, &'static str)> {
|
||||||
-> Option<(Span, &'static str)> {
|
|
||||||
fn may_slice(cx: &LateContext, ty: &ty::Ty) -> bool {
|
fn may_slice(cx: &LateContext, ty: &ty::Ty) -> bool {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TySlice(_) => true,
|
ty::TySlice(_) => true,
|
||||||
|
@ -462,12 +467,11 @@ fn derefs_to_slice(cx: &LateContext, expr: &Expr, ty: &ty::Ty)
|
||||||
ty::TyArray(_, size) => size < 32,
|
ty::TyArray(_, size) => size < 32,
|
||||||
ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) |
|
ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) |
|
||||||
ty::TyBox(ref inner) => may_slice(cx, inner),
|
ty::TyBox(ref inner) => may_slice(cx, inner),
|
||||||
_ => false
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let ExprMethodCall(name, _, ref args) = expr.node {
|
if let ExprMethodCall(name, _, ref args) = expr.node {
|
||||||
if &name.node.as_str() == &"iter" &&
|
if &name.node.as_str() == &"iter" && may_slice(cx, &cx.tcx.expr_ty(&args[0])) {
|
||||||
may_slice(cx, &cx.tcx.expr_ty(&args[0])) {
|
|
||||||
Some((args[0].span, "&"))
|
Some((args[0].span, "&"))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -476,10 +480,14 @@ fn derefs_to_slice(cx: &LateContext, expr: &Expr, ty: &ty::Ty)
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TySlice(_) => Some((expr.span, "")),
|
ty::TySlice(_) => Some((expr.span, "")),
|
||||||
ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) |
|
ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) |
|
||||||
ty::TyBox(ref inner) => if may_slice(cx, inner) {
|
ty::TyBox(ref inner) => {
|
||||||
Some((expr.span, ""))
|
if may_slice(cx, inner) {
|
||||||
} else { None },
|
Some((expr.span, ""))
|
||||||
_ => None
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,10 +37,7 @@ impl LateLintPass for PrintLint {
|
||||||
None => (span, "print"),
|
None => (span, "print"),
|
||||||
};
|
};
|
||||||
|
|
||||||
span_lint(cx,
|
span_lint(cx, PRINT_STDOUT, span, &format!("use of `{}!`", name));
|
||||||
PRINT_STDOUT,
|
|
||||||
span,
|
|
||||||
&format!("use of `{}!`", name));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,8 +211,8 @@ fn lint_shadow<T>(cx: &LateContext, name: Name, span: Span, lspan: Span, init: &
|
||||||
&format!("{} is shadowed by {} which reuses the original value",
|
&format!("{} is shadowed by {} which reuses the original value",
|
||||||
snippet(cx, lspan, "_"),
|
snippet(cx, lspan, "_"),
|
||||||
snippet(cx, expr.span, "..")),
|
snippet(cx, expr.span, "..")),
|
||||||
expr.span,
|
expr.span,
|
||||||
"initialization happens here");
|
"initialization happens here");
|
||||||
note_orig(cx, db, SHADOW_REUSE, prev_span);
|
note_orig(cx, db, SHADOW_REUSE, prev_span);
|
||||||
} else {
|
} else {
|
||||||
let db = span_note_and_lint(cx,
|
let db = span_note_and_lint(cx,
|
||||||
|
@ -221,8 +221,8 @@ fn lint_shadow<T>(cx: &LateContext, name: Name, span: Span, lspan: Span, init: &
|
||||||
&format!("{} is shadowed by {}",
|
&format!("{} is shadowed by {}",
|
||||||
snippet(cx, lspan, "_"),
|
snippet(cx, lspan, "_"),
|
||||||
snippet(cx, expr.span, "..")),
|
snippet(cx, expr.span, "..")),
|
||||||
expr.span,
|
expr.span,
|
||||||
"initialization happens here");
|
"initialization happens here");
|
||||||
note_orig(cx, db, SHADOW_UNRELATED, prev_span);
|
note_orig(cx, db, SHADOW_UNRELATED, prev_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
src/utils.rs
14
src/utils.rs
|
@ -209,7 +209,7 @@ pub fn path_to_def(cx: &LateContext, path: &[&str]) -> Option<cstore::DefLike> {
|
||||||
loop {
|
loop {
|
||||||
let segment = match path_it.next() {
|
let segment = match path_it.next() {
|
||||||
Some(segment) => segment,
|
Some(segment) => segment,
|
||||||
None => return None
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
for item in &mem::replace(&mut items, vec![]) {
|
for item in &mem::replace(&mut items, vec![]) {
|
||||||
|
@ -229,8 +229,7 @@ pub fn path_to_def(cx: &LateContext, path: &[&str]) -> Option<cstore::DefLike> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,13 +249,17 @@ pub fn get_trait_def_id(cx: &LateContext, path: &[&str]) -> Option<DefId> {
|
||||||
|
|
||||||
/// Check whether a type implements a trait.
|
/// Check whether a type implements a trait.
|
||||||
/// See also `get_trait_def_id`.
|
/// See also `get_trait_def_id`.
|
||||||
pub fn implements_trait<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>, trait_id: DefId, ty_params: Option<Vec<ty::Ty<'tcx>>>) -> bool {
|
pub fn implements_trait<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>, trait_id: DefId,
|
||||||
|
ty_params: Option<Vec<ty::Ty<'tcx>>>)
|
||||||
|
-> bool {
|
||||||
cx.tcx.populate_implementations_for_trait_if_necessary(trait_id);
|
cx.tcx.populate_implementations_for_trait_if_necessary(trait_id);
|
||||||
|
|
||||||
let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, None);
|
let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, None);
|
||||||
let obligation = traits::predicate_for_trait_def(cx.tcx,
|
let obligation = traits::predicate_for_trait_def(cx.tcx,
|
||||||
traits::ObligationCause::dummy(),
|
traits::ObligationCause::dummy(),
|
||||||
trait_id, 0, ty,
|
trait_id,
|
||||||
|
0,
|
||||||
|
ty,
|
||||||
ty_params.unwrap_or_default());
|
ty_params.unwrap_or_default());
|
||||||
|
|
||||||
traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation)
|
traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation)
|
||||||
|
@ -658,6 +661,7 @@ pub fn is_expn_of(cx: &LateContext, mut span: Span, name: &str) -> Option<Span>
|
||||||
(ei.callee.name(), ei.call_site)
|
(ei.callee.name(), ei.call_site)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
match span_name_span {
|
match span_name_span {
|
||||||
Some((mac_name, new_span)) if mac_name.as_str() == name => return Some(new_span),
|
Some((mac_name, new_span)) if mac_name.as_str() == name => return Some(new_span),
|
||||||
None => return None,
|
None => return None,
|
||||||
|
|
Loading…
Reference in a new issue