Update specs to match OTP definitions #14121
                
     Merged
            
            
          
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Many typespecs did not exactly match the underlying implementation. For example. File.read can throw an error atom that is not defined inside File.posix() type.
This change does not have the expected effect of generating a warning on patterns that are unable to match such as
Because dialyzer is treating any union type with more than 13 members as the common type. When using File.posix() any atom is considered to be acceptable by dialyzer.
Even though type checking passes I think it makes sense to add the full specification in order to have complete documentation and make sure any implementation of type checking would be compatible.
The code is a bit repetitive because every instance of posix() is followed by :badarg. We could make a new type to encompass posix() + :badarg but it might be better to keep it the same as OTP implementation.
Somewhat related questions:
I noticed we don't have a matching implementation for the third options of copy function that uses a tuple of
{filename :: binary, mode()}as arguments. Is it intentional?Another question, since we wrap many of :file module functions in Elixir, does it make sense to wrap :file.format_error too and return a binary instead of char list?