Skip to content

Fix error caused by recursion into Self. #10068

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

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
Member

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
Contributor

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
Member

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