Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-1846] "Variable used in its own initial value" error when using a function (not a variable) of the same name #44455

Open
swift-ci opened this issue Jun 21, 2016 · 11 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself feature A feature request or implementation

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-1846
Radar rdar://problem/22374793
Original Reporter ayaka (JIRA User)
Type Bug

Attachment: Download

Environment

Xcode Version 7.3.1 (7D1014)
Xcode Version 8.0 beta (8S128d)

Xcode Version 10.2

Additional Detail from JIRA
Votes 14
Component/s Compiler
Labels Bug, LanguageFeatureRequest
Assignee None
Priority Medium

md5: 6bf3d6604bae951be26a31a7e1d23712

is duplicated by:

  • SR-3040 Variable used within its own initial value error for functions with labels
  • SR-5916 Assigning to var from func of same prefix throws compiler error
  • SR-10233 Can't initialize var with function call whose stem is the same as the var name
  • SR-13404 Swift 5 Compiler Fails to Distinguish Variable from Function

relates to:

  • SR-10295 Unexpected ambiguity error when trying to use variable with the same name as an instance member

Issue Description:

For example:

func length(of string: String) -> Int {
return string.characters.count
}

let length = length(of: "Hello world")

emits an error `Variable used in its own initial value`.

I often find myself wanting to use the pattern, like:
let localizedString = localizedString(from: "someKey")
but because of the error, I end up artificially changing the name of the function to something like getLocalizedString or the variable to a slightly different name, which doesn’t feel very Swift-y or in line with the new API design guidelines.

I’m sure there’s a good reason why it’s an error, but it would be reallllly nice if there is a workaround for this for the sake of writing nicer code. 🙂

Thanks!

@belkadan
Copy link
Contributor

I think we currently check this at parse-time, so we'd have to either move the check to Sema (type-checking) or make it smarter / more lax without accidentally allowing closure self-reference.

@itaiferber
Copy link
Contributor

Looks like this is still outstanding. We just ran into this in PR-16238 with

let type = type(of: value:)

Not sure if there's much we can do about this now, but this would still be nice.

@belkadan
Copy link
Contributor

belkadan commented Aug 8, 2018

You generally have the workaround of using the module name to disambiguate (Swift.type(of: value)).

@itaiferber
Copy link
Contributor

Yep, and that's what we're using. 🙂 Still, seems like something that could be made better in cases where it's intuitively clear to the reader that this is not ambiguous (e.g. in almost all cases not involving closures).

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 2, 2018

Comment by Rufus Neumann (JIRA)

A related problem is when you try to redefine a binding, e.g.

let foo: Int? = 1 // note: 'foo' previously declared here
let foo: Int = foo! // error: variable used within its own initial value, error: invalid redeclaration of 'foo'

Possible workaround:

let foo: Int = {
    let foo: Int? = 1
    return foo!
}()

@sethfri
Copy link

sethfri commented Dec 21, 2018

Just hit this (again - hit it the first time in SR-5916 and had forgotten) and was very confused by it. The workaround mentioned by @belkadan above doesn't work when you're calling a private function, and even when it does work it's non-obvious and aesthetically unpleasing 🙁

It looks like this bug has been "In Progress" since May 2017. Since rmnblm (JIRA User)'s profile has been inactive since then, I'm moving this back to Unassigned and Open for someone to pick up.

@belkadan
Copy link
Contributor

For the case in SR-5916, you'd use self.foo, but yeah.

@phoney
Copy link
Mannequin

phoney mannequin commented Apr 28, 2019

This is probably a related issue:

func foo() -> Int { return 1}
func whatever() {    
     let foo = 5    
     let foo1 = foo()     // Error: Cannot call value of non function type Int
}

The compiler doesn't seem to recognize that foo() is a function in scope and not a variable.

I run into these two errors frequently.

The number of duplicate bug reports indicates this is a common pain point.

@belkadan
Copy link
Contributor

That's more of SR-1687.

@phoney
Copy link
Mannequin

phoney mannequin commented Apr 29, 2019

How does a variable shadow a function?

Anyway, more like https://bugs.swift.org/browse/SR-9096

@swift-ci
Copy link
Collaborator Author

swift-ci commented Jun 2, 2021

Comment by Lennart Stolz (JIRA)

If I get the author's (ayaka (JIRA User)) intention right, this issue should be resolved by these changes:

Remove parse-time name lookup by @slavapestov.

The following test case covers this case:

test/NameLookup/name_lookup.swift#L661-L664

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself feature A feature request or implementation
Projects
None yet
Development

No branches or pull requests

4 participants