Skip to content

Conversation

Nashenas88
Copy link

@Nashenas88 Nashenas88 commented Dec 12, 2022

fixes #10041

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

  • Followed [lint naming conventions][lint_naming] - N/A
  • Added passing UI tests (including committed .stderr file)
  • cargo test passes locally
  • Executed cargo dev update_lints - N/A
  • Added lint documentation - N/A
  • 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.

Fixes rust-lang#10041.

Prevent recusion into Self when it's a generic parameter.
Added regression test from example in rust-lang#10041.
@rustbot
Copy link
Collaborator

rustbot commented Dec 12, 2022

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Alexendoo (or someone else) soon.

Please see the contribution instructions for more information.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Dec 12, 2022
@Nashenas88
Copy link
Author

If this fix is not sufficient, I also created a revert with #10069

@Nashenas88
Copy link
Author

Let me know if I should remove the changelog line above since this is a fix.

@xFrednet
Copy link
Contributor

Hey @Nashenas88, this is worth a changelog entry. It would be good if it lists the lint the error was caused in and a rough example which code caused it. In this case, it might be: "... when a function returned a impl PartialOrd with Self as a generic parameter"

@Nashenas88
Copy link
Author

Note regarding the SegFault: It's not an actual memory issue but a stack overflow. When the failing test is loaded with lldb:

$ LD_LIBRARY_PATH="$(rustc --print sysroot)/lib" lldb -- "/home/pfaria/projects/rust-clippy/target/debug/clippy-driver" "tests/ui/new_ret_no_self.rs" "-L" "/home/pfaria/projects/rust-clippy/target/debug/test/ui" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-C" "prefer-dynamic" "-o" "/home/pfaria/projects/rust-clippy/target/debug/test/ui/new_ret_no_self.stage-id" "-A" "unused" "--emit=metadata" "-Dwarnings" "-Zui-testing" "-L" "dependency=/home/pfaria/projects/rust-clippy/target/debug/deps" "--extern" "serde_derive=/home/pfaria/projects/rust-clippy/target/debug/deps/libserde_derive-594fb542f1f177ec.so" "--extern" "clippy_lints=/home/pfaria/projects/rust-clippy/target/debug/deps/libclippy_lints-50aa57c872d0223d.rlib" "--extern" "futures=/home/pfaria/projects/rust-clippy/target/debug/deps/libfutures-acc8d1997e1f7e0b.rlib" "--extern" "syn=/home/pfaria/projects/rust-clippy/target/debug/deps/libsyn-398439f8842a173e.rlib" "--extern" "tokio=/home/pfaria/projects/rust-clippy/target/debug/deps/libtokio-ac7c70827a3f4579.rlib" "--extern" "clippy_utils=/home/pfaria/projects/rust-clippy/target/debug/deps/libclippy_utils-3cc4bf33c9a5a46e.rlib" "--extern" "derive_new=/home/pfaria/projects/rust-clippy/target/debug/deps/libderive_new-0f743cc2315fced6.so" "--extern" "quote=/home/pfaria/projects/rust-clippy/target/debug/deps/libquote-ed7ec3e9296df6b8.rlib" "--extern" "serde=/home/pfaria/projects/rust-clippy/target/debug/deps/libserde-b3c27244e992bf22.rlib" "--extern" "if_chain=/home/pfaria/projects/rust-clippy/target/debug/deps/libif_chain-3ed9e4025056074c.rlib" "--extern" "parking_lot=/home/pfaria/projects/rust-clippy/target/debug/deps/libparking_lot-cf826ae0ca353931.rlib" "--extern" "itertools=/home/pfaria/projects/rust-clippy/target/debug/deps/libitertools-7c57f9592610df5c.rlib" "--extern" "regex=/home/pfaria/projects/rust-clippy/target/debug/deps/libregex-63ef9cefc58b78e2.rlib" "--extern" "rustc_semver=/home/pfaria/projects/rust-clippy/target/debug/deps/librustc_semver-748148245ecd7cc2.rlib" "--edition=2021" "-L" "/home/pfaria/projects/rust-clippy/target/debug/test/ui/new_ret_no_self.stage-id.aux"

and entering run, it hits this segfault:

Process 155307 stopped
* thread #2, name = 'rustc', stop reason = signal SIGSEGV: address access protected (fault address: 0x7fffebfffff8)
    frame #0: 0x00007ffff517bb35 librustc_driver-0b5734e0ecfae6dd.so`<rustc_middle::ty::walk::TypeWalker as core::iter::traits::iterator::Iterator>::next + 5
librustc_driver-0b5734e0ecfae6dd.so`<rustc_middle::ty::walk::TypeWalker as core::iter::traits::iterator::Iterator>::next:
->  0x7ffff517bb35 <+5>:  pushq  %r13
    0x7ffff517bb37 <+7>:  pushq  %r12
    0x7ffff517bb39 <+9>:  pushq  %rbx
    0x7ffff517bb3a <+10>: subq   $0xc8, %rsp

And looking at the backtrace with bt, it's 49,535 frames deep when it hits the segfault:

    frame #49532: 0x00007ffff7c8bf5d librustc_driver-0b5734e0ecfae6dd.so`std::sys::unix::thread::Thread::new::thread_start::ha0be813dd2c37563 [inlined] _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h41a68158edcb5cdd at boxed.rs:2000:9
    frame #49533: 0x00007ffff7c8bf56 librustc_driver-0b5734e0ecfae6dd.so`std::sys::unix::thread::Thread::new::thread_start::ha0be813dd2c37563 at thread.rs:108:17
    frame #49534: 0x00007ffff3694b43 libc.so.6`start_thread(arg=<unavailable>) at pthread_create.c:442:8
    frame #49535: 0x00007ffff3726a00 libc.so.6`__clone3 at clone3.S:81

And they all center around the updated function:

    frame #49494: 0x00005555563f9261 clippy-driver`clippy_utils::ty::contains_ty_adt_constructor_opaque::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h43b5c9a4ce8c219e(ty=Ty @ 0x00007fffec7edff0) at ty.rs:94:43

@Nashenas88
Copy link
Author

@xFrednet let me know if you'd like me to add any additional detail or change any wording here.

@Nashenas88
Copy link
Author

Also, do I need to amend the commit with the changelog, or is it pulled from the github description instead?

@tmandry
Copy link
Member

tmandry commented Dec 15, 2022

This is fixing a bug introduced last week, do we need a changelog entry if it isn't released? (Though this will probably need a beta backport, based on timing.)

r? @dswij
cc @nbdd0121

@rustbot rustbot assigned dswij and unassigned Alexendoo Dec 15, 2022
@nbdd0121
Copy link
Member

Sorry for the problem caused, but ideally I'd hope #9733 is not reverted because we have code that uses pattern in #7344.

I did some poking and discovered that similar recursion can happen for assoc types as well, when using TAIT:

#![feature(type_alias_impl_trait)]
type X = impl std::ops::Add<Output=X>;

struct Foo;

impl Foo {
    fn new() -> X {
        return 1;
    }
}

A more reliable solution might be to have a FxHashSet to track all checked Tys?

For a temporary solution, I suppose we can just get rid of recursion in contains_ty_adt_constructor_opaque, by replacing the recursive contains_ty_adt_constructor_opaque(cx, ty, needle) call with ty == needle || ty.ty_adt_def() == needle.ty_adt_def().

@xFrednet
Copy link
Contributor

Thank you for the updated and detailed description.

Also, do I need to amend the commit with the changelog, or is it pulled from the github description instead?

The entry is pulled from the GH description. Otherwise, it would also produce a bunch of merge conflicts.

This is fixing a bug introduced last week, do we need a changelog entry if it isn't released? (Though this will probably need a beta backport, based on timing.)

It can take some time until PRs land on master. With this one, I hope to have it merged and back ported. This is very likely, and then we won't need a changelog entry. It's still better to have one in the description, in case it does take longer.

@Alexendoo
Copy link
Member

Thanks for that @nbdd0121, I had been trying to find if there were a case like that but couldn't think of one

@matthiaskrgr
Copy link
Member

matthiaskrgr commented Dec 15, 2022

I got this pr + the changes of #10068 (comment) together in branch and x.py test at least passes. 🎉

edit: #10081

matthiaskrgr pushed a commit to matthiaskrgr/rust-clippy that referenced this pull request Dec 15, 2022
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`.
bors added a commit that referenced this pull request Dec 15, 2022
Stack overflow fix

See #10068 (comment) for details

-- original PR description of #10068 --

fixes #10041

Prevent recursion into Self when it's a generic parameter. Added regression test from example in #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)>
matthiaskrgr pushed a commit to matthiaskrgr/rust-clippy that referenced this pull request Dec 15, 2022
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`.
bors added a commit that referenced this pull request Dec 15, 2022
Stack overflow fix

See #10068 (comment) for details

-- original PR description of #10068 --

fixes #10041

Prevent recursion into Self when it's a generic parameter. Added regression test from example in #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)>
@Nashenas88
Copy link
Author

@matthiaskrgr do we want to go with your PR then, and I'll close this one and #10069 ?

@matthiaskrgr
Copy link
Member

my pr didn't work fully and I'm not sure how to fix it unfortunately 😅

@tmandry
Copy link
Member

tmandry commented Dec 15, 2022

I think we should go ahead and revert then, all the reasoning in https://forge.rust-lang.org/compiler/reviews.html#reverts applies here.

bors added a commit that referenced this pull request Dec 16, 2022
Fix new_return_no_self with recursive bounds

Fix #10041

This uses a hash set, as described in #10068 (comment)

changelog: [`new_return_no_self`]: fix stack overflow when the return type is `impl Trait` and contains recursive bounds
@bors
Copy link
Contributor

bors commented Dec 16, 2022

☔ The latest upstream changes (presumably #10086) made this pull request unmergeable. Please resolve the merge conflicts.

@dswij
Copy link
Member

dswij commented Dec 16, 2022

We just merged a forward-fix for this: #10086.

@Nashenas88 Nashenas88 closed this Dec 17, 2022
@Nashenas88 Nashenas88 deleted the fix-forward branch December 17, 2022 20:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clippy crashes on simple method returning impl PartialOrd
9 participants