File.info, File.info? and File#info return Crystal::System::FileInfo instead of File::Info. Crystal::System::FileInfo is an internal struct that should never be returned by any public method.
File.new("hello", mode: "w").info? # => Crystal::System::FileInfo(@stat=LibC::Stat(@st_dev=125_u64, @st_ino=584904_u64, @st_nlink=1_u64, @st_mode=33188_u32, @st_uid=1000_u32, @st_gid=1000_u32, @__pad0=0, @st_rdev=0_u64, @st_size=0_i64, @st_blksize=4096_i64, @st_blocks=0_i64, @st_atim=LibC::Timespec(@tv_sec=1555525911_i64, @tv_nsec=826665407_i64), @st_mtim=LibC::Timespec(@tv_sec=1555525911_i64, @tv_nsec=826665407_i64), @st_ctim=LibC::Timespec(@tv_sec=1555525911_i64, @tv_nsec=826665407_i64), @__glibc_reserved=StaticArray[0_i64, 0_i64, 0_i64]))
Crystal::System::FileInfo is a File::Info by inheritance - if it wasn't, the : Info return types wouldn't compile. The purpose of Crystal::System namespace is to provide platform-specific implementations.
https://github.com/crystal-lang/crystal/blob/master/src/file.cr#L126
Implementations: Windows, Unix
In this way Crystal::System::FileInfo is constructed at compile time depending on platform, where File::Info dictates the higher level, abstract API.
Why do you think it shouldn't be returned? It is an "internal" struct, in that users aren't supposed to construct it / work with it themselves. They should only to expect that File.info returns a File::Info, or in this case, something that implements File::Info.
I agree with @r00ster91 , Crystal::System types shouldn't be leaked to users.
It just needs an .as(File::Info) to make sure the compiler doesn't leak the concrete type.
@RX14 What I find there is that there's a type hierarchy for File::Info when that might not be needed. Why methods on File::Info don't delegate to Crystal::System::FileInfo?
Most helpful comment
@RX14 What I find there is that there's a type hierarchy for
File::Infowhen that might not be needed. Why methods onFile::Infodon't delegate toCrystal::System::FileInfo?