Skip to content

Commit

Permalink
fix recursion in case of type_alias_impl_trait
Browse files Browse the repository at this point in the history
See rust-lang#10068 (comment) for details

-- original PR description of rust-lang#10068 --

fixes rust-lang#10041

Prevent recursion into Self when it's a generic parameter. Added regression test from example in rust-lang#10041.

- \[x] Followed [lint naming conventions][lint_naming] - **N/A**
- \[x] Added passing UI tests (including committed `.stderr` file)
- \[x] `cargo test` passes locally
- \[x] Executed `cargo dev update_lints` - **N/A**
- \[x] Added lint documentation - **N/A**
- \[x] Run `cargo dev fmt`

changelog: [`new-ret-no-self`] Fix segmentation fault caused when generic parameter defaults to `Self` and is unspecified. For example, `fn uh_oh(&self) -> impl PartialOrd { ... }` has a hidden `Rhs=Self` as the generic parameter for `PartialOrd`.
  • Loading branch information
nbdd0121 authored and matthiaskrgr committed Dec 15, 2022
1 parent a56abe8 commit eecec91
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 15 deletions.
2 changes: 1 addition & 1 deletion clippy_utils/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
.types()
.skip(1) // Skip the implicit `Self` generic parameter
.filter(|inner_ty| *inner_ty != ty) // Skip any other `Self` generic parameters
.any(|ty| contains_ty_adt_constructor_opaque(cx, ty, needle))
.any(|ty| ty == needle || ty.ty_adt_def() == needle.ty_adt_def())
{
return true;
}
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/new_ret_no_self.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![feature(type_alias_impl_trait)]
#![warn(clippy::new_ret_no_self)]
#![allow(dead_code)]

Expand Down Expand Up @@ -411,3 +412,15 @@ mod issue10041 {
}
}
}

mod issue10041_TAIT {
type X = impl std::ops::Add<Output = X>;

struct Foo;

impl Foo {
fn new() -> X {
return 1;
}
}
}
26 changes: 12 additions & 14 deletions tests/ui/new_ret_no_self.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:49:5
--> $DIR/new_ret_no_self.rs:50:5
|
LL | / pub fn new(_: String) -> impl R<Item = u32> {
LL | | S3
Expand All @@ -9,88 +9,86 @@ LL | | }
= note: `-D clippy::new-ret-no-self` implied by `-D warnings`

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:81:5
--> $DIR/new_ret_no_self.rs:82:5
|
LL | / pub fn new() -> u32 {
LL | | unimplemented!();
LL | | }
| |_____^

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:90:5
--> $DIR/new_ret_no_self.rs:91:5
|
LL | / pub fn new(_: String) -> u32 {
LL | | unimplemented!();
LL | | }
| |_____^

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:126:5
--> $DIR/new_ret_no_self.rs:127:5
|
LL | / pub fn new() -> (u32, u32) {
LL | | unimplemented!();
LL | | }
| |_____^

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:153:5
--> $DIR/new_ret_no_self.rs:154:5
|
LL | / pub fn new() -> *mut V {
LL | | unimplemented!();
LL | | }
| |_____^

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:171:5
--> $DIR/new_ret_no_self.rs:172:5
|
LL | / pub fn new() -> Option<u32> {
LL | | unimplemented!();
LL | | }
| |_____^

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:224:9
--> $DIR/new_ret_no_self.rs:225:9
|
LL | fn new() -> String;
| ^^^^^^^^^^^^^^^^^^^

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:236:9
--> $DIR/new_ret_no_self.rs:237:9
|
LL | fn new(_: String) -> String;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:271:9
--> $DIR/new_ret_no_self.rs:272:9
|
LL | / fn new() -> (u32, u32) {
LL | | unimplemented!();
LL | | }
| |_________^

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:298:9
--> $DIR/new_ret_no_self.rs:299:9
|
LL | / fn new() -> *mut V {
LL | | unimplemented!();
LL | | }
| |_________^

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:368:9
--> $DIR/new_ret_no_self.rs:369:9
|
LL | / fn new(t: T) -> impl Into<i32> {
LL | | 1
LL | | }
| |_________^

error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:389:9
--> $DIR/new_ret_no_self.rs:390:9
|
LL | / fn new(t: T) -> impl Trait2<(), i32> {
LL | | unimplemented!()
LL | | }
| |_________^

error: aborting due to 12 previous errors

0 comments on commit eecec91

Please sign in to comment.