diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2015-06-29 15:56:00 -0700 |
|---|---|---|
| committer | Huon Wilson <dbau.pp+github@gmail.com> | 2015-06-29 16:00:54 -0700 |
| commit | 900af2c6d9b21ca1b1db35b7b09b0fb59cf78b84 (patch) | |
| tree | 950dd34f3e2171a26f64072976d5d57ab43e7562 | |
| parent | b1931e48a01b418b4b1ba6c747f2c99a5b10d96f (diff) | |
| download | rust-900af2c6d9b21ca1b1db35b7b09b0fb59cf78b84.tar.gz rust-900af2c6d9b21ca1b1db35b7b09b0fb59cf78b84.zip | |
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.
| -rw-r--r-- | src/librustc_lint/builtin.rs | 9 | ||||
| -rw-r--r-- | src/test/compile-fail/lint-unconditional-recursion.rs | 7 |
2 files changed, 16 insertions, 0 deletions
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 3d5eb422b63..190e2965e76 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -2007,6 +2007,15 @@ impl LintPass for UnconditionalRecursion { // 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() } diff --git a/src/test/compile-fail/lint-unconditional-recursion.rs b/src/test/compile-fail/lint-unconditional-recursion.rs index 0cd71aebd63..47bb7f948a7 100644 --- a/src/test/compile-fail/lint-unconditional-recursion.rs +++ b/src/test/compile-fail/lint-unconditional-recursion.rs @@ -67,4 +67,11 @@ fn all_fine() { let _f = all_fine; } +// issue 26333 +trait Bar { + fn method<T: Bar>(&self, x: &T) { + x.method(x) + } +} + fn main() {} |
