-
-
Notifications
You must be signed in to change notification settings - Fork 409
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
LLVM Crash with using a private type as default value outside of the package #4130
Comments
The code in OP fails even if one doesn't use a union type when calling the method. Here's a more minimal example: // In the "lib" pacakge
primitive _Private
primitive Public
fun apply[T](v: (T | _Private) = _Private): None => None
// In main
use lib = "lib"
actor Main
new create(env: Env) =>
let p = lib.Public.apply[U8]()
env.out.print(p.string()) The problem here is that ponyc/src/libponyc/type/lookup.c Lines 66 to 79 in ff5e8c2
Since the
|
This was discussed in the last ~20m or so of the sync call. Today in Pony, we allow private types to be in the parameter types or return type of a public function signature. It may be considered by some to be "bad practice" to do so, but it is allowed. So for consistency with that, I think we'd have to also allow the default argument expression to name a private type (as was being attempted in this example). However, one of the things I have been thinking about lately relates to the automatic detection of breaking changes in type signatures, for tooling to assist with semantic versioning. The challenge there is that if we allow private types to be the return type of a public function, then all public functions of the private type become part of the public API contract to be upheld with respect to semantic versioning. So with that in mind, I think I'd be in favor of a breaking change to Pony language to disallow private types to be named in the public method signatures of a public type. Gordon and red were both surprised that Pony allows this today and agreed with the idea of disallowing it. |
While allowing private values as a default did provide a convenient way of providing a "hidden default," I have to admit that in the back of my mind it did feel like it wasn't a totally legitimate use of the language. So, I am inclined to agree that it should be flagged as a compile time error. |
So the allowing of private types like this was core to the RFC to change collections iterators so its a well trod path at the moment for many in terms of it being discussed a lot. Both on at least 1 sync call, in Zulip, and as the basis for a very discussed RFC. I am not in favor of changing that behaviour without an RFC to consider the ramifications. I would like for us to say that we will fix this bug as it stands without touching anything related to private visibility outside of a package if explicitly provided. That should only be done if an RFC is accepted. I'd like to get others to agree first though. I know we have a user who is interested in fixing this issue so I'd like to come to some agreement as to what we do next. |
Fixing the current bug as it exists makes sense to me, as long as the investment to do so is not too high. |
We discussed this more at today's sync. Sean has spent time looking at how semver tooling would need to apply in the light of the current Pony behavior of allowing private types to be returned in a public method/field - such types would have to be marked as being "exported" by the package despite being private, and thus their public methods/fields would also be considered package-public. This would need to be applied transitively in order to determine which private types have public methods/fields that are package-public. This rule would be correct for current Pony under the definition of correctness that says "a change to a package is not a breaking change if it is not possible to write a downstream program that could be broken by that change". Also, I noticed that even though this conversation has drifted toward disallowing this use case for semantic versioning tooling simplicity reasons, the use case in this ticket (accepting a private parameter type and/or using a private type name in the default expression value) does not actually have the effect of "exporting" that private type, using the definition we discussed above - it would only be considered "exported" if it was in the return type. |
The problem is as @ergl pointed out there are 2 ways to fix: one allowing this use of a private parameter type and the other disallowing it and displaying an error message. Has the sync produced a concensus re: this? |
The inability to use the private parameter is a bug and will be fixed. It shouldn't be a compiler error as nothing is wrong with the example code. It's valid Pony. |
@SeanTAllen What about the poor code in lookup.c (potential compiler crash) I pointed out to you? Should this be fixed separately? Or should I monitor this issue and point it out when proposed changes have been PR-ed? |
Please open issues for anything that isn't specifically the fix to this issue or PRs if you want. |
This attempts to fix issues ponylang#4130 and ponylang#4153. The issue was when a private type in another package was used as a default value in a method call. Fix to ponylang#4130 Since it has been decided to treat this as a bug instead of a missing error, this PR implements the fix suggested by @ergl, namely using `lookup_try()` instead of lookup() in call.c's `check_partial_function_call()` since it allows to permit private types. Fix to ponylang#4153 This is also a simply fix to lookup.c that prevents a potential segfault by a dereferencing of `opt` (`typecheck_t* t = &opt->check;`) *before* `opt != NULL` was checked. As pointed out by @SeanTAllen, opt should not be NULL to begin with when lookup_nominal is called, and instead, an assert should be added and the NULL checks in that function removed.
This attempts to fix ponylang#4130 This crash stems from the use of a private type as defined in another package when it was used as a default value in a method call. Since it has been decided to treat this as a bug instead of a missing error, this PR implements the fix suggested by @ergl, namely using `lookup_try()` instead of lookup() in call.c's `check_partial_function_call()` since the former can be configured to permit private types. Fix to ponylang#4153 This is a simply change to `lookup_nominal()` in lookup.c that prevents a potential segfault by a dereferencing of `opt` (`typecheck_t* t = &opt->check;`) *before* `opt != NULL` was checked. As pointed out by @SeanTAllen, opt should not be NULL to begin with when `lookup_nominal()` is called, and instead, an assert should be added and the NULL checks in that function removed. With this PR, the two examples below that crashed the compiler now both compile: Original example: ```pony // inside the "useful" package primitive _PrivateDefault actor Useful[A: Any val] fun tag config(value: (A | _PrivateDefault) = _PrivateDefault): Useful[A] => this // inside "main" use "useful" primitive This primitive That type Stuff is (This | That) actor Main new create(env: Env) => let u = Useful[Stuff].config() ``` Minimal example: ```pony // In the "lib" pacakge primitive _Private primitive Public fun apply[T](v: (T | _Private) = _Private): None => None // In main use lib = "lib" actor Main new create(env: Env) => let p = lib.Public.apply[U8]() env.out.print(p.string()) ```
When declaring a type as private to a package, but then using that value as the default value
poncy
crashes (SIGSEGV
) withinllvm
with the following message:PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Code to reproduce the error
Commentary indicating the possible source of the problem
See:
method_def
incheck_partial_function_call
ends up beingnull
.See also
The text was updated successfully, but these errors were encountered: