mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 20:46:07 +03:00
Auto merge of #26666 - huonw:unc-rec, r=alexcrichton
This fixes two false positives for the unconditional recursion lint, when functions use themselves (or almost-themselves) internally, without actually being recursive.
````rust
fn main() { let _ = main; }
```
```rust
trait Bar {
fn method<T: Bar>(&self, x: &T) {
x.method(x)
}
}
```
This commit is contained in:
@@ -1973,8 +1973,13 @@ fn id_refers_to_this_fn<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
fn_id: ast::NodeId,
|
||||
_: ast::Ident,
|
||||
id: ast::NodeId) -> bool {
|
||||
tcx.def_map.borrow().get(&id)
|
||||
.map_or(false, |def| def.def_id() == local_def(fn_id))
|
||||
match tcx.map.get(id) {
|
||||
ast_map::NodeExpr(&ast::Expr { node: ast::ExprCall(ref callee, _), .. }) => {
|
||||
tcx.def_map.borrow().get(&callee.id)
|
||||
.map_or(false, |def| def.def_id() == local_def(fn_id))
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
// check if the method call `id` refers to method `method_id`
|
||||
@@ -2002,6 +2007,15 @@ fn id_refers_to_this_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
// method instead.
|
||||
ty::MethodTypeParam(
|
||||
ty::MethodParam { ref trait_ref, method_num, impl_def_id: None, }) => {
|
||||
|
||||
let on_self = m.substs.self_ty().map_or(false, |t| t.is_self());
|
||||
if !on_self {
|
||||
// we can only be recurring in a default
|
||||
// method if we're being called literally
|
||||
// on the `Self` type.
|
||||
return false
|
||||
}
|
||||
|
||||
tcx.trait_item(trait_ref.def_id, method_num).def_id()
|
||||
}
|
||||
|
||||
|
||||
@@ -63,4 +63,15 @@ fn qux(&self) { //~ ERROR function cannot return without recurring
|
||||
}
|
||||
}
|
||||
|
||||
fn all_fine() {
|
||||
let _f = all_fine;
|
||||
}
|
||||
|
||||
// issue 26333
|
||||
trait Bar {
|
||||
fn method<T: Bar>(&self, x: &T) {
|
||||
x.method(x)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
Reference in New Issue
Block a user