Skip to content

[SR-11001] Collections description ends up invoking debugDescription of elements #53391

Open
@ktoso

Description

@ktoso
Previous ID SR-11001
Radar rdar://problem/63898476
Original Reporter @ktoso
Type Bug
Additional Detail from JIRA
Votes 3
Component/s Standard Library
Labels Bug
Assignee None
Priority Medium

md5: 1d0d6cf976a9b368d4533a89dca6f9ab

Issue Description:

Swift version Apple Swift version 5.0-dev (LLVM f961e3dd74, Swift ff641d3)

Let's say I have a carefully designed type with information which is definitely enough for users to identify and observe a value, as well as some "very internal, noone should care, unless debugging" state:

  1> struct Thing: CustomStringConvertible, CustomDebugStringConvertible {
  2.     let name: String
  3.     let _hidden: String
  4.     let _dontTellAnyone: String
  5.     public var description: String {
  6.         return "DESC: \(name)"
  7.     }
  8.     public var debugDescription: String {
  9.         return "DEBUG: \(name) \(_hidden) \(_dontTellAnyone)"
 10.     }
 11. }
 12> let thing = Thing(name: "Bob", _hidden: "hello long text", _dontTellAnyone: "so many words!!!")
thing: Thing = {
  name = "Bob"
  _hidden = "hello long text"
  _dontTellAnyone = "so many words!!!"
}

Printing the type works as expected:

 13> "\(thing)"
$R0: String = "DESC: Bob"
 14> ["\(thing)"]
$R1: [String] = 1 value {
  [0] = "DESC: Bob"
}

Yet printing it as part of a collection now, which users of my library may happen to do:

 15> "\([thing])"
$R2: String = "[DEBUG: Bob hello long text so many words!!!]"

Now all that carefully hidden state is being printed while invoking the collection's `.description` ⚠️


This seems like an omission / confusion;

Current behavior

 16> String(describing: [thing])
$R3: String = "[DEBUGL Bob hello long text so many words!!!]"
 17> String(reflecting: [thing])
$R4: String = "[DEBUGL Bob hello long text so many words!!!]"

Expected behavior

 16> String(describing: [thing])
$R3: String = "[DESC: Bob]"
 17> String(reflecting: [thing])
$R4: String = "[DEBUGL Bob hello long text so many words!!!]"

The reason this happens seems to be that all collections share an implementation here, which ends up calling debugPrint(item, regardless if debug printing or not: https://github.com/apple/swift/blob/e9d827ca3c809f511ebb53d169d6ce11d396eec3/stdlib/public/core/ArrayShared.swift#L83

Happy to work on a fix if this indeed was an oversight and not intended behavior (albeit quite weird one then).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.standard libraryArea: Standard library umbrella

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions