Skip to content

Commit 900af2c

Browse files
committed
lint: default methods must be called on Self to unconditionally recur.
This catches the case when a trait defines a default method that calls itself, but on a type that isn't necessarily `Self`, e.g. there's no reason that `T = Self` in the following, so the call isn't necessarily recursive (`T` may override the call). trait Bar { fn method<T: Bar>(&self, x: &T) { x.method(x) } } Fixes #26333.
1 parent b1931e4 commit 900af2c

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

src/librustc_lint/builtin.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,6 +2007,15 @@ impl LintPass for UnconditionalRecursion {
20072007
// method instead.
20082008
ty::MethodTypeParam(
20092009
ty::MethodParam { ref trait_ref, method_num, impl_def_id: None, }) => {
2010+
2011+
let on_self = m.substs.self_ty().map_or(false, |t| t.is_self());
2012+
if !on_self {
2013+
// we can only be recurring in a default
2014+
// method if we're being called literally
2015+
// on the `Self` type.
2016+
return false
2017+
}
2018+
20102019
tcx.trait_item(trait_ref.def_id, method_num).def_id()
20112020
}
20122021

src/test/compile-fail/lint-unconditional-recursion.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,11 @@ fn all_fine() {
6767
let _f = all_fine;
6868
}
6969

70+
// issue 26333
71+
trait Bar {
72+
fn method<T: Bar>(&self, x: &T) {
73+
x.method(x)
74+
}
75+
}
76+
7077
fn main() {}

0 commit comments

Comments
 (0)