Generic Attributes#17258
Conversation
❗ Release notes required
|
|
Adding of test cases, and fullfilment of minutia (documentation, various "feature" tags, general cleanup, etc) still WIP. Currently, [<SomeAttribute<int>()>] compiles down to the expected IL. I plan to explore what will be required for inferencing before marking as ready. Drafting now while I complete the minor details in case anyone wants to provide feedback in the meantime. |
…ign with apparent standard
…SecurityAttribute (ILxGen)
|
@dotnet-policy-service agree company="Hillcrest Research and Development LLC" |
|
Hi @mflibby, this looks very interesting! In your original description, can you link to the reported issue that this is fixing? And if it is a language change (i.e., a new feature that is being added), can you link to the RFC (in https://github.com/fsharp/fslang-design) and the language proposal or discussion chat (https://github.com/fsharp/fslang-suggestions)? If none exist, can you update the OP with a summary of what this change is doing and why? |
|
@abelbraaksma I've updated the description with the desired information. Please let me know if this is satisfactory, or if more information will be helpful :) |
|
I'm not sure why, but commit 64607ef passed all checks, yet after a few cleanup/a minor change/merges to other changes on main, a large number of the checks have been failing (the only substantive change I made since the passing commit was a minor change to the LexFilter that allowed the type arguments immediately adjacent to the close of an attribute list to be properly parsed). I'm wondering why I am all of a sudden getting a bunch of seemingly unrelated tests failing? Additionally, windows defender seems to be flagging a bunch of tests, and occasionally quarantining innocuous tests like "Conformance/../E_Literals02.fs". The investigation continues. |
|
|
||
| module Attribute = | ||
|
|
||
| let verifyCompilation compilation = |
There was a problem hiding this comment.
Could you please add test cases(s) with mutual recursion (either via and or via a rec module) between the attribute declaration, the type argument and the type it is being applied on?
There was a problem hiding this comment.
Do we have a particular point of failure we are looking for here? Off the top of my head this is what comes to mind:
(in a module rec)
type MyAttribute<^T>() =
inherit Attribute()
[<MyAttribute<AnActualType>>]
let x = 1
type AnActualType = class end(Note: it appears that in a rec module, the usage of an attribute on a binding needs to occur after the definition, but on a type it can occur before the definition.)
and maybe something like
(in a regular module)
[<MyAttribute<AnActualType>>]
type SomeClass(arg) =
member _.AGoodProperty = arg
and MyAttribute<^T>() =
inherit Attribute()
and AnActualType = intThere was a problem hiding this comment.
Oh great call, both rec and and fail right now (made sure to check they pass when there are no type args and both do)
There was a problem hiding this comment.
Glad I could suggest a point of failure - I did not have a particular one in mind, I just know that rec modules are a common point of failure for new typechecking features.
Maybe also a type applying "itself" as the type argument to the attribute?
[<MyAttribute<SomeClass<SomeClass<SomeClass<MyAttribute>>>>>]
type SomeClass<'a>(arg) =
There was a problem hiding this comment.
I still need to figure out why the rec/and cases failed, but I implemented the self referencing case (great case btw, I know there must be some cases where it will be useful but this in particular made me laugh quite hard), and was surprised to find it working right out of the gate!
Hey @mflibby, excellent, thanks, now we know where it's coming from and that it was approved 👍. We still need an RFC, though. I may be able to help with that. Language changes require an RFC for documentation and consensus. They capture the what, how and scope of any new feature. The go here: https://github.com/fsharp/fslang-design. It is also used to set up a discussion thread to deal with any unresolved questions. I can help with the process. |
| let envForTypeDef (tdef: ILTypeDef) = { EnclosingTyparCount=tdef.GenericParams.Length } | ||
| let envForMethodRef env (ty: ILType) = { EnclosingTyparCount=(match ty with ILType.Array _ -> env.EnclosingTyparCount | _ -> ty.GenericArgs.Length) } | ||
| let envForNonGenericMethodRef _mref = { EnclosingTyparCount=Int32.MaxValue } | ||
| //let envForNonGenericMethodRef _mref = { EnclosingTyparCount=Int32.MaxValue } do we need this for attributes? It doesn't appear so |
There was a problem hiding this comment.
I realize it's generally a "no-no" to do this to obscure functionality (i.e. I dont yet understand what this was for), but it seems that with the introduction of generic attributes, we will need to fully qualify the environment for attribute usage. Since this function was only used in the generation of attributes, my current position is that this function can be deleted - though I am still curious why the count was being maxed for the non-generic case, if anyone has that wisdom on hand.
There was a problem hiding this comment.
Rule of thumb is usually:
We have one more case - when we introduced another resource for nullability data, it has multiple problems unfortunately:
We probably want to think of such mechanism in future, but it will require a very thorough design and will be a huge chunk of work.
Not necessary, main purpose is to have/store additional metadata, which we want to use cross-assembly (mostly). I don't really think it will affect perf significatly.
Yeah, but please, refer to part of this comment below - not all the info we would like to have is in the IL metadata. TL;DR - I would personally go with second point in the beginning of my comment if possible. We have done it before. We will likely do it in future. And at the moment we, unfortunately, don't have a better mechanism for it. |
|
I would like to see more interop tests,
There probably needs to be work to ensure that the IDE experience of Generic Attributes works OK, but I think that can be a separate PR. Needs a language flag so at least we have about a year to work through the kinks. Needs a much more detailed writeup of what's enabled, why, and what the interop experience is supposed to be. This looks like a good start, thanks for taking care of it. |
|
We'll convert this to draft for now, due to low activity. @mflibby ping us if you need help :) |
|
It would be nice to finally have them |
Yeah my apologies for letting this drift a little, I have a project at work that really ramped up at the end of May so this fell by the wayside. I fully intend on returning to this and busting it out the rest of the way starting January. I will definitely take you up on that offer as I know that there are several things that are confusing me in terms of both the build process and general path-forward development things.
I look forward to getting back to this :) |
|
@mflibby no need to apologize, we all get overwhelmed by stuff sometimes :) Happy you're going to be back in a game! On that note, seeing that it's your first PR in F#, I would like to suggest you joining the Amplifying F# initiative. Folks in AF# can be happy and fast to answer all (or most of) the questions you've put here. Moreover, recently we've started doing community PR reviews and I thought this one can be also a good case for such a session - generic attributes are a rather hard yet interesting topic and this can be a great learning exercise for the community (and maintainers as well, me for sure :D) @edgarfgp et al will guide through the process then. |
Just adding a feature for language version
Anywhere under
One important thing to remember, is that you want to run tests (not debug them) in the Release configuration, since it's what we care codegen-wise the most, I think this is what you were facing. Otherwise, we can solve it as it comes.
Not Kevin, but I think either here or in the suggestion/RFC would be a good place for it to be. |
…lows Reinforce noop requirement at key decision points: - repo-assist: Command Mode exit path and Task FINAL fallthrough - regression-pr-shepherd: When no eligible PRs exist Fixes #17258 workflow failure (no safe outputs produced) Agent-Logs-Url: https://github.com/dotnet/fsharp/sessions/ac165649-72fa-4613-bd06-fcdc9604f176 Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
Description
Resolves FSLang 965
RFC FS-1143
Intention:
The intent of this PR is to implement Generic Attribute support, e.g.:
Checklist