Skip to content

[AST][SILOptimizer]: unify missing return diagnostics in some cases #75574

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

Merged
merged 1 commit into from
Aug 9, 2024

Conversation

jamieQ
Copy link
Contributor

@jamieQ jamieQ commented Jul 30, 2024

Previously, missing return diagnostics for unreachable subscripts differed from the treatment unreachable functions received, leading to inconsistent diagnostic behavior. This change removes the responsibility for handling the relevant diagnostics from the AST code, in favor of the diagnostics implemented via the SIL optimizer. Additionally, where the AST-generation code would previously have diagnosed a missing return for an implicit empty getter, it will now admit as valid, deferring the missing return diagnostics to the later SIL passes.

Resolves #74210.

@jamieQ
Copy link
Contributor Author

jamieQ commented Aug 1, 2024

@hamishknight i took a stab at addressing the issue outlined in #74210. would appreciate feedback if this approach looks like a feasible option if/when you have some time. thanks in advance!

Copy link
Contributor

@hamishknight hamishknight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Comment on lines 8059 to 8060
consumeEmptyBraces();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect we can also remove this branch too since not having a result type means we don't have a TypedPattern, which will be diagnosed in parseDeclVarGetSet (and it looks like parseDeclSubscript always diagnoses a null type and sets an ErrorTypeRepr). This means we ought to be able to inline consumeEmptyBraces into the parsingLimitedSyntax case too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, so to clarify what i think is happening & what you're proposing – this branch seems like it was added via #40705 to address this sort of thing:

var x = true {} // error: unexpected '{' in declaration

if i remove the logic, the diagnostics change, but the scenario still appears to be handled in a reasonable manner (to me, anyway). e.g. if the unexpected_curly_braces_in_decl diagnostic path is removed (aside: it looks like this is its only use, so it's another diagnostic that can perhaps be removed entirely), then parsing produces:

var x = true {} // error: computed property must have an explicit type

if we add a type annotation, given the changes proposed in this PR, we successfully parse the code, but typechecking fails with:

var x: Bool = true {} // error: variable with getter/setter cannot have an initial value

so given the other suggested branch removal, the final logic for this conditional would be something like:

  1. if we're parsing in the limited syntax mode, consume the empty braces
  2. otherwise, parse an implicit getter
  3. in both cases, return a parser success

locally this appeared to pass tests other than the affected error message change mentioned above. if this sounds accurate to you, i'll try to clean up this code and update the tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that seems reasonable to me. If we wanted to improve things further, we could add a special-cased diagnostic for when you both have an initializer and an empty accessor body (regardless of whether you have a type); since in that case it's more likely than not the user is intending to write a didSet/willSet accessor.

@jamieQ jamieQ force-pushed the missing-return-diagnostics branch from 4df3747 to 8d78f79 Compare August 5, 2024 23:53
// expected-error@-1 {{missing return in accessor expected to return 'Int'}}
// expected-error@-3 {{result builder attribute 'Maker' can only be applied to a variable if it defines a getter}}
// expected-error@-1{{result builder 'Maker' does not implement any 'buildBlock' or a combination of 'buildPartialBlock(first:)' and 'buildPartialBlock(accumulated:next:)' with sufficient availability for this call site}}
// missing return expectations moved to `SILOptimizer/missing_returns`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: There's no missing return expectation for this case :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, i don't think i follow... i added similar code to the missing_returns tests but this formulation is now valid if the result builder protocol is satisfied. there's no expectation b/c this is now 'fixed'. seemed like it should be moved there though since this test doesn't do the SIL pass. should this be worded differently, or am i misunderstanding?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry yeah I just meant this should be worded differently since the issue isn't a lack of return

Comment on lines 1347 to 1355
// https://github.com/apple/swift/issues/57936

enum E1_57936 {
var foo: Int {} // expected-error{{missing return in accessor expected to return 'Int'}}
var foo: Int {} // missing return expectations moved to `SILOptimizer/missing_returns`
}

enum E2_57936<T> {
var foo: T {} // expected-error{{missing return in accessor expected to return 'T'}}
var foo: T {} // missing return expectations moved to `SILOptimizer/missing_returns`
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests were only added to check the diagnostic, so I think we can remove them here in favor of the ones in the SILOptimizer test

Previously, missing return diagnostics for unreachable subscripts
differed from the treatment unreachable functions received, leading to
inconsistent diagnostic behavior. This change removes the responsibility
for handling the relevant diagnostics from the AST code, in favor of the
diagnostics implemented via the SIL optimizer. Additionally, where the
AST-generation code would previously have diagnosed a missing return for
an implicit empty getter, it will now admit as valid, deferring the
missing return diagnostics to the later SIL passes.
@jamieQ jamieQ force-pushed the missing-return-diagnostics branch from 8d78f79 to 6c676c9 Compare August 7, 2024 13:16
subscript(_ i: Int) -> Int {} // expected-error{{missing return in getter expected to return 'Int'}}
subscript(_ j: Int) -> Void {}
subscript(_ k: Int) -> Never {} // expected-error{{getter with uninhabited return type 'Never' is missing call to another never-returning function on all paths}}
// FIXME: ^ this diagnostic should probably use the word 'subscript' rather than 'getter'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noticed this wording change when moving to the SIL-based diagnostics. i have yet to determine how to special case the relevant logic to improve this. let me know if this seems like a blocker.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's a blocker, it's the same diagnostic we give today for e.g:

struct S {
  subscript(_ x: Int) -> Never {
    let x = 0
  }
}

@jamieQ jamieQ marked this pull request as ready for review August 7, 2024 13:20
@hamishknight
Copy link
Contributor

@swift-ci please test

@hamishknight hamishknight merged commit e65647c into swiftlang:main Aug 9, 2024
5 checks passed
@jamieQ jamieQ deleted the missing-return-diagnostics branch August 9, 2024 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Subscript produces bad diagnostic for uninhabited types
2 participants