apple / swift-xcode-playground-support

Logging and communication to allow Swift toolchains to communicate with Xcode.
Apache License 2.0
284 stars 65 forks source link

[SR-8196] Xcode Beta 3: Fatal error: Only BidirectionalCollections can be advanced by a negative amount #67

Closed swift-ci closed 6 years ago

swift-ci commented 6 years ago
Previous ID SR-8196
Radar rdar://problem/41976357
Original Reporter possen@gmail.com (JIRA User)
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment Xcode Beta 3 MacBook Air OS X High Sierra
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Xcode Playground Support | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: d9ee1a3d8bd5234232986876e8fce714

Issue Description:

When I create playground with the code below, I get the following error when running.

Fatal error: Only BidirectionalCollections can be advanced by a negative amount

It seems editing parts of the text out can cause the error to go away. I don't see how this code goes backward in the collection. I was able to make it happen when in an App as well as a playground.

If I pass the string in as a parameter to the function I also don't get the error.

let text = """

What was Bruce Lee’s cause of death? Matthew Polly, the author of the excellent new biography “Bruce Lee: A Life,” has a strange, sad, and entirely plausible explanation.

Polly digs deep into how Lee died in our new “Shoot This Now” podcast, which you can listen to on iTunes or here:

The cause of Bruce Lee’s death is one of the most confounding questions in his spectacular life: How did a 32-year-old man who exercised constantly and was known for toned physique suddenly die? Misinformation abounds.

Now Playing: Fitness Nut Shows Off His Impressive Balancing Skills

Fitness nut Travis Horn showed off his impressive balancing skills while on top of multiple dumbbells and wine glasses. Travis takes balance to a whole new level and claims his skills are “a mixture between god’s power and Bruce lee’s mindset.” Credit: The balance guru via Storyful

Media: Storyful

Also Read: 'Jaws 2' Was Almost 'Saving Private Ryan' With Sharks (Podcast)

Google “How did Bruce Lee die” and you’ll receive, thanks to Quora, the most common answer: cerebral edema. A cerebral edema is an excess accumulation of fluid in the brain that can cause seizures, coma, and even respiratory arrest.

Lee collapsed on May 10, 1973, while recording dialogue for his film, “Enter the Dragon.” He was taken to a Hong Kong hospital where doctors diagnosed him with cerebral edema. So it is probably not surprising that when Lee died suddenly on July 20, 1973, another Hong Kong hospital reported that cerebral edema was the cause of death.

A Hong Kong inquest later found Lee’s cause of death to be “death by misadventure,” a type of accidental death that involves a degree of bad luck. That finding included the possibility that one factor in Lee’s death was his decision to take a drug called Equagesic, which contained aspirin and a tranquilizer.

Also Read: How Bruce Lee Used Kung Fu to Beat Bigotry (Podcast)

But Polly argues persuasively on our podcast that Lee’s real cause of death may have been overheating. And his overheating may have been intensified by a decision to have his “sweat glands removed from his armpits because he felt his dripping pits looked bad onscreen,” as Polly writes in his book. “Without these sweat glands, his body would have been less able to dissipate heat.”

Yes: It is possible to have the sweat glands of the armpits removed. But Polly argues it was a dangerous decision for someone who exercised as intensely as Lee did.

Overheating is better understood today than it was in 1973. But it is “the third-most-common killer of athletes and rises to first during the hottest months of summer,” Polly explains. Lee died on the hottest day of July 1973.

Also Read: About That Drake Cultural Appropriation Debate... (Podcast)

Polly’s book carefully unpacks the rumors and misinformation around Lee — which were fed by a decision to remove his body from the home of his mistress, Betty Ting Pei, to avoid upsetting his family.

If Lee did die, in part, because of the decision to remove the sweat glands from his armpits, it would be a tragic turn in his lifelong quest to excel. Lee worked hard for his entire life to overcome every obstacle, first to impress his father and later to provide for his wife, Linda, and their two children. He was relentlessly competitive, always seeking an edge, and always willing to sacrifice to succeed.

He traveled to Hong Kong to make films after Hollywood couldn’t overcome its racism to make him a leading man in an American film. He became the greatest martial arts star in the world, against unbelievable odds.

His death cut short a courageous struggle for success. And the mystery around it has contributed to the fascination with his too-short life.

the end.

"""

//let text1 = """

// Hello world how are you today.

// His death cut short a courageous struggle for success. And the mystery around it has contributed to the fascination with his too-short life.

//

// """

let nibFile = NSNib.Name("MyView")

var topLevelObjects : NSArray?

let words = text.split(separator: " ")

let counts = words.reduce(into: [String: Int]()) {

$0\[String($1), default: 0\] += 1

}

counts

print(words)

Bundle.main.loadNibNamed(nibFile, owner:nil, topLevelObjects: &topLevelObjects)

let views = (topLevelObjects as! Array\<Any>).filter { $0 is NSView }

// Present the view in Playground

PlaygroundPage.current.liveView = views[0] as! NSView

belkadan commented 6 years ago

cc @milseman

@swift-ci create

177d8476-2756-4152-91d7-984f74d3896c commented 6 years ago

The precondition fires when Collection's implementation of offsetBy-based index is invoked rather than BidirectionalCollection's. This might be directly, or indirectly invoked via a method like distance. The question is, why is something producing a negative offset in a context generic over Collection and not BidirectionalCollection?

ee21ea02-9d7a-4385-8c3c-ad21e8e490a8 commented 6 years ago

And the answer is https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md#overloading-across-constrained-extensions

TL;DR: the least restricted overload is picked when in generic context to allow for more types. Not sure where in the snippet above said generic context happens, though.

belkadan commented 6 years ago

Karoy tracked this down to a playground-specific issue, which was fixed in https://github.com/apple/swift-xcode-playground-support/pull/26.

belkadan commented 6 years ago

You did say you managed to get this to reproduce in an app, so if you see this again outside of a playground and you're not calling index(_:offsetBy:) yourself, please let us know!

swift-ci commented 6 years ago

Comment by Paul Ossenbruggen (JIRA)

Apologies, I could have sworn it failed in the project but I admit I was in a bit of a hurry. I attached the updated project and all the tests pass, so you are correct, a playground issue. Thanks for resolving this issue so quickly!