-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Test plan for "ref readonly" and related features (7.2) #19216
Comments
FYI @VSadov @OmarTawfik I'll start gathering ideas for test plan. |
After talking with @cston, it seems that we need to add tests for both EnC and EE for:
I was going to do that in #18715, but this is getting too big of a PR, so I'll keep it for later. |
Is this doc up-to-date, so I can review it to see what's needed to make the debugging experience good? |
Turns out it isn't. Specifically https://github.com/dotnet/csharplang/blob/master/proposals/readonly-ref.md#metadata-representaion. |
@OmarTawfik So we are not using custom modifiers anywhere? Last time I heard we used a mix. How do we mark local variables that are |
@OmarTawfik Could you update the spec please? |
@tmat. Yes. I'll send a PR out later. |
@OmarTawfik Thanks! |
@jcouv about this part:
The current design doesn't prohibit such scenario. Can you explain? |
* dotnet/master: Report binding error for typed LINQ query on a type expression (dotnet#22412) clean up more refactoring Fixed tests fix test after rebase one more test CR feedback Allow taking unmanaged/pinned addresses of readonly variables. Fix typo in INotifyCompletion API in doc (dotnet#22417) Fix serialization of attribute data to account for named params argument (dotnet#22231) Create tests to cover test plans dotnet#19216 and dotnet#20127 (dotnet#22284) Checked uses of RefKind.RefReadOnly String rename Check for null before registering incremental analyzer in work coordinator. clean up Create tests to cover test plans dotnet#19216 and dotnet#20127
Write a test plan for "ref readonly", "readonly structs", "ref and ref readonly extensions" and "ref ternary"
LDM
in
syntax from initial release? (merged)ref readonly
at call site (for those who dislike auto-ref)? (yes, but we're switching toin
as keyword)Spec
in
parameters are not allowed in iterator or async methodsvar x = stackalloc ...
is pointer type for compat reasons, butcondition ? stackalloc ... : stackalloc ...
isSpan
)Misc
ref readonly
,in
,return ref ...
,ref
ternary,in
versusref readonly
readonly struct
ref readonly
at call site, CodeStyle for call site (for those who don't like auto-ref)Ref readonly parameters
Spec exists
test passing too many modifiers ("ref readonly in" or "in ref readonly", etc)
verify API declaration and usage from compilation, image, metadata-only image and ref assembly
ref readonly property from metadata with different attributes on getter and property
Where is it allowed or blocked?
out
orparams
(expect error)ref readonly
is disallowed: in local declarationsref readonly var x = y;
, in front of expressionsvar x = ref readonly y;
,return ref readonly
,foreach (readonly ref i in ...)
in
andref readonly
in lambdain
in delegatein
in local functionin
in async and iterator methods (disallowed)in
orref readonly
at call site (disallowed)ref
andreadonly
does matter (what is the error? should we offer a fixer?)in
in pattern-based lowering:Deconstruct
method within
parameters is not applicable for deconstructionin
in builder typeGetEnumerator(in int count = 10)
(see Overload resolution for GetEnumerator fails with optional parameters #19742)OHI
ref/out/in
(we only consider types)M(1);
withvoid M(ref readonly int i) { }
andvoid M(int i) { }
in situation of ambiguity (because of inheritance or extension methods)verify
in
is invariant (because of CLR limitation, just likeout
)Verify that IL for copy versus no-copy
M(someInArg, async M2(), someOtherInArg)
-
someInArg
could be local, constant,RefReadonlyM(refReadonlyField)
,someArray[index]
,field
No writes allowed:
ref
in S s
, thens.Mutate();
) (also allowed, operating on a temp copy, verify IL. But no copy ifS
is readonly struct)in
through is okin
parameters cannot be captured (lambda/async/iterator)in
allowed in indexer and operator parameterstest VB interop (calling blocked because modreq on overridable members and delegate/interface methods, but allowed on non-overridable members)
taking pointer to ref readonly parameter (in unsafe code) is disallowed
passing
nameof
expression asin
argument (expect copy?)Ref readonly returns
Spec exists
in
syntax disallowed in method declarationref readonly
return in async method (no syntax for it)ref readonly
return on operator is disallowed (no syntax for it)ref readonly
on indexer (allowed)readonly
is disallowed inreturn
statementsignature needs exact match in OHI
in
andref
ref-readonly-returning lambda?
calling with a discard (no syntax for it?)
metadata:
IsReadOnlyAttribute
gets embbeded if not found, disallowed in sourceInAttribute
modreq present butIsReadOnlyAttribute
is missing, then cannot load metadataIsReadOnlyAttribute
is present, butInAttribute
modreq is missing, then can load and this absence of modreq will be carried over when overriding.Readonly struct
readonly
on class declaration and other illegal membersreadonly
is floating, butref
must be next tostruct
inreadonly ref struct
partial
must be beforeref
orstruct
(but what about thereadonly
?)in
structreadonly
on half a partial struct (allowed, just like other modifiers)Obsolete
attribute given by user wins. There should be a warning.void M(in S s)
withM(this)
, but notvoid M(ref S s)
.void M(S s)
withM(this)
, but that will make a copy.this
cannot be captured by lambda or otherthis
is disallowedRef ternary
(b ? ref x : ref y).M()
whereM
is ref extension method, regular extension method (error), regular method (error)x
ory
or both are readonly structs?M(b ? ref x : ref y)
wherevoid M(in ...)
, I expect no temporary.b ? ref M() : ref M2()
whereref readonly C M()
(and same for M2), expect the ternary is readonlyb ? ref this : ref this
wherethis
refers to a readonly struct, is the ternary readonly?b
is known to be constant (compiler knows which branch will be executed)?b ? ref x : y
b1 ? ref (b2 ? ref x : ref y) : ref z
ref x ?? ref y
b ? ref x : ref default
(disallowed)in
argument (M(in condition ? ref x : ref y);
)Ref readonly extension methods
ref readonly S Extension(ref readonly this S s) { return ref s; }
void RRExtension<T>(ref readonly this T t) { ... }
(expect error)42.RRExtension()
(ok, but makes temporary)readonlyField.RRExtension()
(expect no temporary)refReadonlyParameter.RRExtension()
(expect no temporary)M().RRExtension()
(expect no temporary)this.RRExtension()
(ref readonly ternary).RRExtension()
(expect no temporary)Ref-like types and safety (Span)
ref readonly string M(ref readonly string s = "hello") { return ref s; }
. Same with value type. (gives a unsafe-to-escape diagnostic)dynamic d = stackalloc int[10];
Span<dynamic> d = stackalloc dynamic[10];
Misc
(b ? ref x : ref x).foo()
x.y.foo() // ref may be inferred
IsReadOnly
andIsByRefLike
are disallowed in sourceSee also
The text was updated successfully, but these errors were encountered: