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-284] Strange error caused by let/var at specific place in main file. #42906

Closed
jepers opened this issue Dec 17, 2015 · 8 comments
Closed

Comments

@jepers
Copy link

jepers commented Dec 17, 2015

Previous ID SR-284
Radar rdar://23702526
Original Reporter @jepers
Type Bug
Status Resolved
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: 49c6b20edc7481c19a41e118ce88ca23

is duplicated by:

  • SR-2727 Script mode rules for top-level bindings are confusing and broken
  • SR-7658 "not declared" error for declarations after statements in binary mode is confusing

relates to:

  • SR-11534 Having a global variable in a wrong place causes a misleading error message

Issue Description:

The unrelated constant notEvenUsed somehow causes the error on struct S. The error will disappear if the constant is moved to another line or removed.
(This happens only in the main file.)

protocol P {
    func +(lhs: Self, rhs: Self) -> Self
}
struct S : P { // Error: Type 'S' does not conform to protocol 'P'
    var v: Int
}
let notEvenUsed = 1 // Move or comment out this line to remove above error.
func +(lhs: S, rhs: S) -> S { return S(v: lhs.v + rhs.v) }
@belkadan
Copy link
Contributor

belkadan commented Dec 18, 2015

In a main source file, declarations are evaluated in groups, but any actual code has to be run immediately, and top-level variables behave like locals rather than globals. That means we try to type-check P and S together before we've even parsed the +.

One way to fix this might be to parse the entire file up front, but then mark the declarations as "off-limits" somehow for type-checking purposes. That won't work for things like overload resolution, though.

@jckarter
Copy link
Member

jckarter commented Dec 18, 2015

More subtly, + is allowed to refer to x, but code that happens before x is declared could refer to the S: P conformance, leading to a use-before-initialization. I think this behaves correctly.

@belkadan
Copy link
Contributor

belkadan commented Dec 18, 2015

I think the restriction is correct, but the error message is lousy. This isn't the first time it's been filed.

@belkadan
Copy link
Contributor

belkadan commented Dec 18, 2015

(and I don't just mean Jens cloning Radars into JIRA. :-) )

@jepers
Copy link
Author

jepers commented Dec 19, 2015

Note that this compiles:

protocol P {
    func +(lhs: Self, rhs: Self) -> Self
}
let notEvenUsed = 1
struct S : P { // Error: Type 'S' does not conform to protocol 'P'
    var v: Int
}
func +(lhs: S, rhs: S) -> S { return S(v: lhs.v + rhs.v) }

@belkadan
Copy link
Contributor

belkadan commented Dec 20, 2015

Yes, that's compiled as

protocol P {
    func +(lhs: Self, rhs: Self) -> Self
}
let notEvenUsed = 1
struct S : P {
    var v: Int
}
func +(lhs: S, rhs: S) -> S { return S(v: lhs.v + rhs.v) }

each block of which is fine given the previous ones.

@belkadan
Copy link
Contributor

belkadan commented Sep 22, 2016

Dups include unsafe behavior caused by this.

@slavapestov
Copy link
Member

slavapestov commented Dec 5, 2019

I didn't find any radars with unsafe behavior, but I suspect its caused by DI not working across files. In any case that problem already exists even with the old intertwined parsing model.

#26636

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants