cyclic type "of infinite size" may not be

44ec281
Opened by comex at 2024-12-21 05:10:34

rustc's error message "cyclic type of infinite size" is produced whenever a type parameter is inferred to refer to the type it's a parameter of, but this does not need to actually result in an infinitely sized type. I think such cyclic types should be allowed, but at minimum the error message should be improved.

For example:

use std::cell::Cell;
struct Foo<'a, T: 'a>(Cell<Option<&'a T>>);
fn main() {
    let foo = Foo(Cell::new(None));
    foo.0.set(Some(&foo));
}

produces:

error[E0308]: mismatched types
 --> test.rs:5:20
  |
5 |     foo.0.set(Some(&foo));
  |                    ^^^^ cyclic type of infinite size
  |
  = note: expected type `&_`
  = note:    found type `&Foo<'_, _>`

error: aborting due to previous error
  1. The problem with cyclic type parameters is not that the struct has an infinite size, but rather the type itself. Trying to describe the type results in an infinitely deep generic which rustc is currently incapable of dealing with. That said, I would like it if rustc could one day be able to deal with such types so they could be allowed, but it isn't a simple fix by any means.

    Peter Atashian at 2016-08-25 08:50:03

  2. Trying to describe the type results in an infinitely deep generic which rustc is currently incapable of dealing with.

    @retep998 Just came across this issue and wondering - how is this not a problem for Box? My understanding is that it should behave very similarly to & (since they are both basically generic pointer types).

    Ingvar Stepanyan at 2017-12-22 23:25:04

  3. I tried these and into same issue:

    Use Box

    let _curry = |argslen: usize| |func| (|args| fixedpoint (|curried
    	, (args, len, )| (|x| if len > 0 
    	{ |x| curried (((Box::new (args), x), len - 1, )) } else 
    	{ func (args) })) ((args, argslen, ))) ;
    

    get

       Compiling playground v0.0.1 (/playground)
    error[E0308]: mismatched types
      --> src/main.rs:94:19
       |
    94 |         { |x| curried (((Box::new (args), x), len - 1, )) } else 
       |                         ^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
    
    For more information about this error, try `rustc --explain E0308`.
    error: could not compile `playground` (bin "playground") due to 1 previous error
    

    Use &

    let _curry = |argslen: usize| |func| (|args| fixedpoint (|curried
    	, (args, len, )| (|x| if len > 0 
    	{ |x| curried (((& args, x), len - 1, )) } else 
    	{ func (args) })) ((args, argslen, ))) ;
    

    get

       Compiling playground v0.0.1 (/playground)
    error[E0308]: mismatched types
      --> src/main.rs:94:19
       |
    94 |         { |x| curried (((& args, x), len - 1, )) } else 
       |                         ^^^^^^^^^^^ cyclic type of infinite size
    
    For more information about this error, try `rustc --explain E0308`.
    error: could not compile `playground` (bin "playground") due to 1 previous error
    

    I don't know did they useful on this question ... just share them.

    ypa y yhm at 2024-03-07 08:45:18