Skip to content

Fix crash-on-invalid when calling non-required init on a metatype #16901

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

Conversation

slavapestov
Copy link
Contributor

We were missing some checks. Reported by a user on Twitter.

If the base value was 'self', we were allowing a reference to a
non-required initializer, because you're allowed to do this inside
another initializer.

But if you're in a static method, 'self.init' should obey the same
restrictions as 'foo.init' for any other metatype value 'foo'.
A static reference to DynamicSelfType can only be written as an
implicit member expression where the contextual type is a
DynamicSelfType, ie, 'return .init(...)' in a static method
returning Self.

In this case, the base expression is not a statically-derived
metatype.
@slavapestov slavapestov requested a review from rudkx May 30, 2018 05:52
@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test

@slavapestov
Copy link
Contributor Author

@swift-ci Please test source compatibility

Copy link
Contributor

@rudkx rudkx left a comment

Choose a reason for hiding this comment

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

Do we have any tests that use 'super.init'?

From a brief glance it's not clear to me that the right thing will necessarily happen in that case.

@slavapestov
Copy link
Contributor Author

Do you mean super.init from inside a static method? I’ll try it out. It should probably be banned

@slavapestov
Copy link
Contributor Author

@rudkx This works right now:

public class C {
  init() {}
}

public class D : C {
  static func f() -> D {
    return super.init()
  }
}

It emits a statically-dispatched call to C.init, just like if you had written return C(). I can add a test case for this in a separate PR if you feel its necessary.

@slavapestov slavapestov merged commit 57ed4fc into swiftlang:master May 30, 2018
@rudkx
Copy link
Contributor

rudkx commented May 30, 2018

I only brought it up because you deleted a line of code checking explicitly for SuperRefExpr and it wasn't clear to me that handling it correctly would just fall out from the remaining code. I'll leave it to your best judgement on whether we're already testing adequately for that.

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.

2 participants