Handle more cases in is_normalizable
By assuming that a recursive type is normalizable within the deeper calls to `is_normalizable_helper()`, more cases can be handled by this function. In order to fix stack overflows, a recursion limit has also been added for recursive generic type instantiations.
This commit is contained in:
parent
76bc88c40f
commit
19ddb6922c
7 changed files with 193 additions and 11 deletions
19
tests/ui/crashes/ice-10508a.rs
Normal file
19
tests/ui/crashes/ice-10508a.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Used to overflow in `is_normalizable`
|
||||
|
||||
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() {}
|
||||
24
tests/ui/crashes/ice-10508b.rs
Normal file
24
tests/ui/crashes/ice-10508b.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
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>);
|
||||
}
|
||||
7
tests/ui/crashes/ice-10508c.rs
Normal file
7
tests/ui/crashes/ice-10508c.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#[derive(Debug)]
|
||||
struct S<T> {
|
||||
t: T,
|
||||
s: Box<S<fn(u: T)>>,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -283,14 +283,30 @@ LL | / enum WithRecursion {
|
|||
LL | | Large([u64; 64]),
|
||||
| | ---------------- the largest variant contains at least 512 bytes
|
||||
LL | | Recursive(Box<WithRecursion>),
|
||||
| | ----------------------------- the second-largest variant contains at least 0 bytes
|
||||
| | ----------------------------- the second-largest variant contains at least 4 bytes
|
||||
LL | | }
|
||||
| |_^ the entire enum is at least 0 bytes
|
||||
| |_^ the entire enum is at least 516 bytes
|
||||
|
|
||||
help: consider boxing the large fields to reduce the total size of the enum
|
||||
|
|
||||
LL | Large(Box<[u64; 64]>),
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
error: large size difference between variants
|
||||
--> tests/ui/large_enum_variant.rs:168:1
|
||||
|
|
||||
LL | / enum LargeEnumWithGenericsAndRecursive {
|
||||
LL | | Ok(),
|
||||
| | ---- the second-largest variant carries no data at all
|
||||
LL | | Error(WithRecursionAndGenerics<u64>),
|
||||
| | ------------------------------------ the largest variant contains at least 516 bytes
|
||||
LL | | }
|
||||
| |_^ the entire enum is at least 516 bytes
|
||||
|
|
||||
help: consider boxing the large fields to reduce the total size of the enum
|
||||
|
|
||||
LL | Error(Box<WithRecursionAndGenerics<u64>>),
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -283,14 +283,62 @@ LL | / enum WithRecursion {
|
|||
LL | | Large([u64; 64]),
|
||||
| | ---------------- the largest variant contains at least 512 bytes
|
||||
LL | | Recursive(Box<WithRecursion>),
|
||||
| | ----------------------------- the second-largest variant contains at least 0 bytes
|
||||
| | ----------------------------- the second-largest variant contains at least 8 bytes
|
||||
LL | | }
|
||||
| |_^ the entire enum is at least 0 bytes
|
||||
| |_^ the entire enum is at least 520 bytes
|
||||
|
|
||||
help: consider boxing the large fields to reduce the total size of the enum
|
||||
|
|
||||
LL | Large(Box<[u64; 64]>),
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
error: large size difference between variants
|
||||
--> tests/ui/large_enum_variant.rs:168:1
|
||||
|
|
||||
LL | / enum LargeEnumWithGenericsAndRecursive {
|
||||
LL | | Ok(),
|
||||
| | ---- the second-largest variant carries no data at all
|
||||
LL | | Error(WithRecursionAndGenerics<u64>),
|
||||
| | ------------------------------------ the largest variant contains at least 520 bytes
|
||||
LL | | }
|
||||
| |_^ the entire enum is at least 520 bytes
|
||||
|
|
||||
help: consider boxing the large fields to reduce the total size of the enum
|
||||
|
|
||||
LL | Error(Box<WithRecursionAndGenerics<u64>>),
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: large size difference between variants
|
||||
--> tests/ui/large_enum_variant.rs:203:5
|
||||
|
|
||||
LL | / enum NoWarnings {
|
||||
LL | | BigBoi(PublishWithBytes),
|
||||
| | ------------------------ the largest variant contains at least 296 bytes
|
||||
LL | | _SmallBoi(u8),
|
||||
| | ------------- the second-largest variant contains at least 1 bytes
|
||||
LL | | }
|
||||
| |_____^ the entire enum is at least 296 bytes
|
||||
|
|
||||
help: consider boxing the large fields to reduce the total size of the enum
|
||||
|
|
||||
LL | BigBoi(Box<PublishWithBytes>),
|
||||
| ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: large size difference between variants
|
||||
--> tests/ui/large_enum_variant.rs:208:5
|
||||
|
|
||||
LL | / enum MakesClippyAngry {
|
||||
LL | | BigBoi(PublishWithVec),
|
||||
| | ---------------------- the largest variant contains at least 224 bytes
|
||||
LL | | _SmallBoi(u8),
|
||||
| | ------------- the second-largest variant contains at least 1 bytes
|
||||
LL | | }
|
||||
| |_____^ the entire enum is at least 224 bytes
|
||||
|
|
||||
help: consider boxing the large fields to reduce the total size of the enum
|
||||
|
|
||||
LL | BigBoi(Box<PublishWithVec>),
|
||||
| ~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 20 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -178,3 +178,65 @@ fn main() {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
mod issue11915 {
|
||||
use std::sync::atomic::AtomicPtr;
|
||||
|
||||
pub struct Bytes {
|
||||
ptr: *const u8,
|
||||
len: usize,
|
||||
// inlined "trait object"
|
||||
data: AtomicPtr<()>,
|
||||
vtable: &'static Vtable,
|
||||
}
|
||||
pub(crate) struct Vtable {
|
||||
/// fn(data, ptr, len)
|
||||
pub clone: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Bytes,
|
||||
/// fn(data, ptr, len)
|
||||
///
|
||||
/// takes `Bytes` to value
|
||||
pub to_vec: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Vec<u8>,
|
||||
/// fn(data, ptr, len)
|
||||
pub drop: unsafe fn(&mut AtomicPtr<()>, *const u8, usize),
|
||||
}
|
||||
|
||||
enum NoWarnings {
|
||||
BigBoi(PublishWithBytes),
|
||||
_SmallBoi(u8),
|
||||
}
|
||||
|
||||
enum MakesClippyAngry {
|
||||
BigBoi(PublishWithVec),
|
||||
_SmallBoi(u8),
|
||||
}
|
||||
|
||||
struct PublishWithBytes {
|
||||
_dup: bool,
|
||||
_retain: bool,
|
||||
_topic: Bytes,
|
||||
__topic: Bytes,
|
||||
___topic: Bytes,
|
||||
____topic: Bytes,
|
||||
_pkid: u16,
|
||||
_payload: Bytes,
|
||||
__payload: Bytes,
|
||||
___payload: Bytes,
|
||||
____payload: Bytes,
|
||||
_____payload: Bytes,
|
||||
}
|
||||
|
||||
struct PublishWithVec {
|
||||
_dup: bool,
|
||||
_retain: bool,
|
||||
_topic: Vec<u8>,
|
||||
__topic: Vec<u8>,
|
||||
___topic: Vec<u8>,
|
||||
____topic: Vec<u8>,
|
||||
_pkid: u16,
|
||||
_payload: Vec<u8>,
|
||||
__payload: Vec<u8>,
|
||||
___payload: Vec<u8>,
|
||||
____payload: Vec<u8>,
|
||||
_____payload: Vec<u8>,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue