Repository: rust
Issue: Compiler bug with cyclic weak references on Windows
Labels: A-linkage,O-windows-msvc,C-bug

I've tracked down the following bug on 1.5 stable. It only appears to happen on Windows, as I've tried the same program on Linux x64 without problems:

`test.rs`:

```
use std::rc::{Rc, Weak};

struct SDVertex {
    start_face: Option<Weak<SDFace>>,
}

impl SDVertex {
    fn new() -> SDVertex {
        SDVertex {
            start_face: None,
        }
    }
}

struct SDFace {
    v: [Option<Weak<SDVertex>>; 3],
}

impl SDFace {
    fn new() -> SDFace {
        SDFace {
            v: [None, None, None],
        }
    }
}

struct LoopSubdiv;

impl LoopSubdiv {
    pub fn test(num_faces: usize) -> Vec<Rc<SDFace>> {
        // Allocate vertices and faces
        let mut fs = Vec::with_capacity(num_faces);
        for _ in 0..num_faces {
            fs.push(Rc::new(SDFace::new()));
        }

        fs
    }
}

fn main() {
    println!("{:?}", (LoopSubdiv::test(4).len(), 4));
}
```

On Linux, I get the expected result:

```
[~/test]$ rustc --version
rustc 1.4.0 (8ab8581f6 2015-10-27)
[~/test]$ rustc -o test test.rs
test.rs:4:5: 4:37 warning: struct field is never used: `start_face`, #[warn(dead_code)] on by default
test.rs:4     start_face: Option<Weak<SDFace>>,
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.rs:8:5: 12:6 warning: method is never used: `new`, #[warn(dead_code)] on by default
test.rs: 8     fn new() -> SDVertex {
test.rs: 9         SDVertex {
test.rs:10             start_face: None,
test.rs:11         }
test.rs:12     }
test.rs:16:5: 16:35 warning: struct field is never used: `v`, #[warn(dead_code)] on by default
test.rs:16     v: [Option<Weak<SDVertex>>; 3],
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[~/test]$ ./test
(4, 4)
```

On Windows, this fails during compilation:

```
[~/test]$ rustc --version
rustc 1.5.0 (3d7cd77e4 2015-12-04)
[~/test]$ rustc -o test test.rs
test.rs:4:5: 4:37 warning: struct field is never used: `start_face`, #[warn(dead_code)] on by default
test.rs:4     start_face: Option<Weak<SDFace>>,
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.rs:8:5: 12:6 warning: method is never used: `new`, #[warn(dead_code)] on by default
test.rs: 8     fn new() -> SDVertex {
test.rs: 9         SDVertex {
test.rs:10             start_face: None,
test.rs:11         }
test.rs:12     }
test.rs:16:5: 16:35 warning: struct field is never used: `v`, #[warn(dead_code)] on by default
test.rs:16     v: [Option<Weak<SDVertex>>; 3],
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: linking with `link.exe` failed: exit code: 1104
note: "D:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC/bin\\amd64\\link.exe" "/LIBPATH:D:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC/lib\\amd64" "/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.10150.0\\ucrt\\x64" "/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\x64" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:D:\\Program Files\\Rust stable 1.5\\bin\\rustlib\\x86_64-pc-windows-msvc\\lib" "test.0.o" "/OUT:test" "/OPT:REF,ICF" "/DEBUG" "/LIBPATH:D:\\Program Files\\Rust stable 1.5\\bin\\rustlib\\x86_64-pc-windows-msvc\\lib" "/LIBPATH:D:\\path\\to\\test\\.rust\\bin\\x86_64-pc-windows-msvc" "/LIBPATH:D:\\path\\to\\test\\bin\\x86_64-pc-windows-msvc" "D:\\Program Files\\Rust stable 1.5\\bin\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-35c36e89.rlib" "D:\\Program Files\\Rust stable 1.5\\bin\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcollections-35c36e89.rlib" "D:\\Program Files\\Rust stable 1.5\\bin\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_unicode-35c36e89.rlib" "D:\\Program Files\\Rust stable 1.5\\bin\\rustlib\\x86_64-pc-windows-msvc\\lib\\librand-35c36e89.rlib" "D:\\Program Files\\Rust stable 1.5\\bin\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-35c36e89.rlib" "D:\\Program Files\\Rust stable 1.5\\bin\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc_system-35c36e89.rlib" "D:\\Program Files\\Rust stable 1.5\\bin\\rustlib\\x86_64-pc-windows-msvc\\lib\\liblibc-35c36e89.rlib" "D:\\Program Files\\Rust stable 1.5\\bin\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-35c36e89.rlib" "ws2_32.lib" "userenv.lib" "advapi32.lib" "kernel32.lib" "shell32.lib" "msvcrt.lib" "compiler-rt.lib"
note: LINK : fatal error LNK1104: cannot open file 'test'

error: aborting due to previous error
```

I first identified this bug while [writing something as part of my ray tracer](https://github.com/Mokosha/pbrt_rust/blob/3a8692d3e241ada04a970af8947a1298f40bc7b7/src/shape/loopsubdiv.rs#L241). It failed to run a fairly simple unit test using `cargo test`. The result for that was:

```
panicked at 'arithmetic operation overflowed', ../src/liballoc\rc.rs:867
```

However, the weird thing is that this only shows up in the library if I change the definition of `SDFace` to

```
struct SDFace {
    v: [Option<Weak<SDVertex>>; 3],
    f: [Option<Weak<SDFace>>; 3],
}

impl SDFace {
    fn new() -> SDFace {
        SDFace {
            v: [None, None, None],
            f: [None, None, None],
        }
    }
}
```

This seems like a bug somewhere, but I don't know where -- if I need to analyze anything additionally, please let me know.