swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.51k stars 10.35k forks source link

[SR-1288] placing a Void result of a call to a mutating method in a variable #43896

Open swift-ci opened 8 years ago

swift-ci commented 8 years ago
Previous ID SR-1288
Radar None
Original Reporter VladimirS (JIRA User)
Type Bug
Environment Swift 3.0 (mar 24) in IBM Swift Sandbox
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, DiagnosticsQoI | |Assignee | None | |Priority | Medium | md5: 96d5ecf385ddc23a1f3756931d6b75eb

Issue Description:

Were discussing a "SE-0059: Update API Naming Guidelines and Rewrite Set APIs Accordingly" in swift-evolution mailing list, and I was posted this example of not obvious code of Swift 3.0(mar 24):

var z1 = [3,2,1]
let z2 = z1.sort() // mutating method!
print(z2) // => ()

Douglas Gregor \dgregor@apple.com\ suggested to fire a bug here:
"It definitely seems reasonable for us to warn on this kind of example, e.g., placing a Void result of a call to a mutating method in a variable. Can you file a ticket a bugs.swift.org? It would be a great starter bug."

belkadan commented 8 years ago

We already produce this warning:

constant 'z2' inferred to have type '()', which may be unexpected

Do we really need another one?

belkadan commented 8 years ago

I suppose we could special-case this one.

swift-ci commented 8 years ago

Comment by Vladimir (JIRA)

Could you let me know, why at all we need the ability to assign Void to variable? Where this could be used?

belkadan commented 8 years ago

Hm. You don't ever need a variable that's directly typed as Void, but you do want to allow generic parameters that are dynamically Void, variables that are Void? (for testing whether optional chaining succeeded), and probably associated types that are Void. That last may necessitate having a Void-typed property, though probably still not a local variable.

swift-ci commented 8 years ago

Comment by Vladimir (JIRA)

@Jordan Rose, thank you for the answer.. but is it possible to express the same in a small snippet of code? For some reason I can't convert your text to code in my head :-) Sorry and thank you.

belkadan commented 8 years ago

Sure.

protocol Recreatable {
  associatedtype Configuration
  init(configuration: Configuration)
  var configuration: Configuration { get }
}

// A normal conforming type.
struct IntWrapper: Recreatable {
  var value: Int
  typealias Configuration = Int
  init(configuration: Int) { self.value = configuration }
  var configuration: Int { return value } 
}

// An unusual conforming type.
struct AlwaysZero: Recreatable {
  var value: Int { return 0 }
  typealias Configuration = Void
  init(configuration: Void) {}
  var configuration: Void { return () }
}
swift-ci commented 8 years ago

Comment by Vladimir (JIRA)

@Jordan Rose, thank you, but I can't see an assignment Void result to local variable anywhere in your code. Probably you can provide such a code?

Also, why this was compiled without errors but raises run-time error :
(was trying to produce a code that will assign a void to variable, but catched this)

protocol Recreatable {
associatedtype Configuration

init(_ configuration: Configuration)
var configuration: Configuration { get }

func preprocess( configuration: Configuration)
}

extension Recreatable {
func doSomething() {
preprocess(configuration: configuration)
}
}

// A normal conforming type.
struct IntWrapper: Recreatable {
typealias Configuration = Int

init(_ configuration: Int) { }
var configuration: Int { get {return 5} }

func preprocess( configuration: Configuration) {}
}

Error running code:
0 swift 0x000000000317d238 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 40
1 swift 0x000000000317ba36 llvm::sys::RunSignalHandlers() + 54
2 swift 0x000000000317dd66
3 libpthread.so.0 0x00007ff573249d10
4 swift 0x0000000000ed0bb1 swift::constraints::ConstraintSystem::addTypeVariableConstraintsToWorkList(swift::TypeVariableType*) + 113
5 swift 0x0000000000ed0db9 swift::constraints::ConstraintSystem::assignFixedType(swift::TypeVariableType*, swift::Type, bool) + 377
6 swift 0x0000000000f2c8cc swift::constraints::ConstraintSystem::matchTypes(swift::Type, swift::Type, swift::constraints::TypeMatchKind, unsigned int, swift::constraints::ConstraintLocatorBuilder) + 4300
......

belkadan commented 8 years ago

That's a coincidence, but mind filing another bug?

My example didn't have an assignment to Void, but it did have a Void-typed variable. As you say, there's no need for a direct assignment to Void, but there's already a warning for that. I don't think we gain anything by turning that warning into an error.

swift-ci commented 8 years ago

Comment by Vladimir (JIRA)

Regarding the Void: I just wanted to see if assignment of Void to local variable can be useful or such assignment should be treated as error(don't think warning is enought here). But I got your opinion. Thank you.

Filling another bug..

Dante-Broggi commented 6 years ago

Is this resolved? If so, this should be closed.