Skip to content
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

ICE: stack overflow in self-referential struct in clippy_utils::ty::is_normalizable_helper #10508

Open
matthiaskrgr opened this issue Mar 15, 2023 · 4 comments
Labels
C-bug Category: Clippy is not doing the correct thing I-ICE Issue: Clippy panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@matthiaskrgr
Copy link
Member

matthiaskrgr commented Mar 15, 2023

Summary

clippy-driver file.rs is enough.

use std::marker::PhantomData;

struct Node<T: 'static> {
    m: PhantomData<&'static T>,
}

struct Digit<T> {
    elem: T,
}

enum FingerTree<T: 'static> {
    Single(T),

    Deep(Digit<T>, Box<FingerTree<Node<T>>>),
}

fn main() {}

Version

rustc 1.70.0-nightly (171693274 2023-03-14)
binary: rustc
commit-hash: 1716932743a7b3705cbf0c34db0c4e070ed1930d
commit-date: 2023-03-14
host: x86_64-unknown-linux-gnu
release: 1.70.0-nightly
LLVM version: 15.0.7

Error output

Backtrace

0x0000555555c54817 in clippy_utils::ty::is_normalizable_helper ()
(gdb) bt
#0  0x0000555555c54817 in clippy_utils::ty::is_normalizable_helper ()
#1  0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#2  0x0000555555c54c79 in clippy_utils::ty::is_normalizable_helper ()
#3  0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#4  0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#5  0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#6  0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#7  0x0000555555c54c79 in clippy_utils::ty::is_normalizable_helper ()
#8  0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#9  0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#10 0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#11 0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#12 0x0000555555c54c79 in clippy_utils::ty::is_normalizable_helper ()
#13 0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#14 0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#15 0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#16 0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()
#17 0x0000555555c54c79 in clippy_utils::ty::is_normalizable_helper ()
#18 0x0000555555c54b29 in clippy_utils::ty::is_normalizable_helper ()

@matthiaskrgr matthiaskrgr added C-bug Category: Clippy is not doing the correct thing I-ICE Issue: Clippy panicked, giving an Internal Compilation Error (ICE) ❄️ labels Mar 15, 2023
@matthiaskrgr matthiaskrgr changed the title ICE: stack overflow ICE: stack overflow in clippy_utils::ty::is_normalizable_helper () Mar 15, 2023
@Jarcho
Copy link
Contributor

Jarcho commented Mar 16, 2023

Was this used in real code? FingerTree can't be instantiated as written.

@matthiaskrgr
Copy link
Member Author

No this was fuzzed

@matthiaskrgr
Copy link
Member Author

another variant

use std::marker::PhantomData;

struct Digit<T> {
    elem: T
}

struct Node<T:'static> { m: PhantomData<&'static T> }

enum FingerTree<T:'static> {
    Single(T),
    
    Deep(
        Digit<T>,
        Node<FingerTree<Node<T>>>,
        )
}

enum Wrapper<T:'static> {
    Simple,
    Other(FingerTree<T>),
}

fn main() {
    let w = 
        Some(Wrapper::Simple::<u32>);
    
}

@matthiaskrgr matthiaskrgr changed the title ICE: stack overflow in clippy_utils::ty::is_normalizable_helper () ICE: stack overflow in self-referential struct in clippy_utils::ty::is_normalizable_helper Dec 16, 2023
@matthiaskrgr
Copy link
Member Author

Another one I think, this compiles fine as is with rustc but clippy stack overflows

#[derive(Debug)]
struct S<T> {
    t: T,
    s: Box<S<fn(u: T)>>,
}

fn main() {}

bors added a commit that referenced this issue Aug 14, 2024
Remove `is_normalizable`

fixes #11915
fixes #9798
Fixes only the first ICE in #10508

`is_normalizable` is used in a few places to avoid an ICE due to a delayed bug in normalization which occurs when a projection type is used on a type which doesn't implement the correct trait. The only part of clippy that actually needed this check is `zero_sized_map_values` due to a quirk of how type aliases work (they don't a real `ParamEnv`). This fixes the need for the check there by manually walking the type to determine if it's zero sized, rather than attempting to compute the type's layout thereby avoid the normalization that triggers the delayed bug.

For an example of the issue with type aliases:
```rust
trait Foo { type Foo; }
struct Bar<T: Foo>(T::Foo);

// The `ParamEnv` here just has `T: Sized`, not `T: Sized + Foo`.
type Baz<T> = &'static Bar<T>;
```

When trying to compute the layout of `&'static Bar<T>` we need to determine if what type `<Bar<T> as Pointee>::Metadata` is. Doing this requires knowing if `T::Foo: Sized`, but since `T` doesn't have an associated type `Foo` in the context of the type alias a delayed bug is issued.

changelog: [`large_enum_variant`]: correctly get the size of `bytes::Bytes`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-ICE Issue: Clippy panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

2 participants