overflow during drop-check on a recursive type

81d08b7
Opened by wolfiestyle at 2024-10-13 00:13:42

I get a pretty strange error when trying to compile this: (playground link)

enum Stuff<T> {
    Value(T),
    Nested(Box<Stuff<Stuff<T>>>),
}

fn main() {
    let a = Stuff::Value(1);
}

output:

error[E0320]: overflow while adding drop-check rules for Stuff<i32>
 --> src/main.rs:7:9
  |
7 |     let a = Stuff::Value(1);
  |         ^
  |
  = note: overflowed on Stuff<Stuff<Stuff<Stuff<Stuff<Stuff< ...

If the type isn't used, the program compiles fine. Don't know if the type is actually representable or not, the error is misleading.

  1. How is it misleading? Stuff::<i32>::Nested contains a Stuff<Stuff<i32>>, which contains a Stuff<Stuff<Stuff<i32>>>, which contains a....

    Steven Fackler at 2017-09-29 23:53:28

  2. I wouldn't call it misleading either, but "overflow while adding drop-check rules" certainly isn't as clear and to-the-point as "Stuff<T> is unrepresentable" would be. It also seems bad that we don't emit this error until the type gets used somewhere.

    Ixrec at 2017-10-15 21:29:09

  3. (I am debating about whether the I-hang label applies here. In my head, stack overflow errors are usually just the result of hangs being caught via very crude means...)

    Felix S Klock II at 2019-03-05 15:26:44

  4. Interestingly, the overflow here doesn't trigger an ICE?

    Felix S Klock II at 2019-03-05 15:29:42

  5. Diagnostics triage: P-low, as it's fairly clear what's going on, just not a great diagnostic message

    Oli Scherer at 2019-05-24 18:26:05

  6. Triage: no change.

    Esteban Kuber at 2022-12-29 22:45:55

  7. Current error:

    error[E0320]: overflow while adding drop-check rules for Stuff<i32>
     --> src/main.rs:9:9
      |
    9 |     let a = Stuff::Value(1);
      |         ^
      |
      = note: overflowed on Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<Stuff<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    
    For more information about this error, try `rustc --explain E0320`.
    

    Dylan DPC at 2024-08-31 04:21:13

  8. @Dylan-DPC surprised that we don't trim the type name in the note and store it to disk. That would be an easy improvement, as well as modifying the message to surround the type name with `.

    Esteban Kuber at 2024-08-31 17:34:18

  9. I've run into a similar error with a type that looks to me to be completely reasonable & only fails to compile in some cases. Perhaps the triage for this issue can be revisited.

    enum Tree<T: Scopable> {
        Group(Vec<Tree<T>>),
        Subtree(Box<Tree<T::SubType>>),
        Leaf(T),
    }
    
    trait Scopable: Sized {
        type SubType: Scopable;
    }
    
    impl<T: Scopable> Tree<T> {
        fn foo(self) -> Self { // error[E0320]: overflow while adding drop-check rules for Tree<T>
            self
        }
    }
    

    playground

    playground + modifications that trigger an ICE

    I was hoping to implement a builder API on Tree, but I don't know any way around this error.

    I did notice that using references in foo do not trigger the drop check overflow, but I can't implement a builder pattern without owned values.

    cyypherus at 2024-10-13 00:11:05