-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Out as return only #64318
Merged
Merged
Out as return only #64318
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
7522f0d
Out change
jaredpar 39ac635
More
jaredpar 7e64550
more
jaredpar e2ef7a3
Fixed out
jaredpar 1312bbb
finishing up
jaredpar 2e18e89
feedback
jaredpar fadfefd
more
jaredpar d90757e
Clean up
jaredpar eee84e7
More
jaredpar 4cee632
more
jaredpar ff1f999
PR feedback
jaredpar 9f2605b
PR feedback
jaredpar d9608af
PR feedback
jaredpar 1503cfc
PR feedback
jaredpar f4b2ce5
Refactor the EscapeLevel anaylsis
jaredpar 6c70c9b
PR feedback
jaredpar a2007a4
PR feedback
jaredpar e11141d
PR feedback
jaredpar f68618c
In person feedback
jaredpar 7d2605b
More
jaredpar 28dd184
RSTE of all ref is return-only
jaredpar dd92bf2
Apply suggestions from code review
jaredpar 99cc78a
more tests
jaredpar b663cb5
PR feedback
jaredpar 3a4577d
PR feedback
jaredpar 6e231a4
More
jaredpar 5536fd1
Tests
jaredpar e20541e
formatting
jaredpar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
543 changes: 361 additions & 182 deletions
543
src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would this scenario work if
[UnscopedRef]
were applied to the method?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. The
[UnscopedRef]
would only apply to theref
portion ofthis
. That doesn't come into play here though as the violation is the following:In this case
s
has a STE of containing method andthis
has STE of return only as we modelthis
as anout
.Also note that we specifically disallow
[UnscopedRef]
on astruct
constructor because it would create some really awkward interactions. At that point the STE and RSTE would be equivalent and the ctor could capture refs to itself. So cyclic self assignment in a ctor. I think we could now model that correctly but have it disallowed because it creates really awkward scenarios and I can't see a scenario in which it would be justified. If one was provided I'd be interested in allowing but it won't help this particular issue.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, of course. STE of
this
is not customizable and neither is STE of ascoped ref
parameter. Thanks!Though I guess if it were possible to say
ref scoped S
, you would be able to value-assignthis
to it. I wonder if that fact is related to whyref scoped
was cut? I wasn't following as closely when that happened.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The initial design only had essentially two scopes: calling method and containing method. A parameter which was
ref scoped
had it's STS set to containing method. That decision though was wrong and it allowed for easy exploitation as follows:This works because the STS of both values was containing method so the assignment just falls out. At the time we realized the mistake here we still were also looking at other unintended design issues we'd created and cut this on a focus of
Now that we've gotten comfortable representing multiple scopes in the design it is possible to model
ref scoped
. For example it could be done effectively as:The relationship between
'd
and'c
means that you can assign these values toscoped
locals but not the other way around. There is very deliberately no relationship because that requires thinking through a bit more.This also introduces the other problem that we have to deal with: variance. Essentially we have to make sure that in the above design
'b ref 'c Span<int>
cannot be assigned to'b ref 'd Span<int>
as that just recreates the original problem. Yet'c Span<int>
can be assigned to'd Span<int>
. That is just assigning aSpan<int>
with some value toscoped Span<int>
which is always safe.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right..with a 2-scope solution, where STE of
ref scoped
parameters is current method, it's sort of unsafe by construction. The caller is essentially saying to the callee, "somehow, I am passing you references to your own local variables".