or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing
xxxxxxxxxx
Pattern matching
Fake Reads
MIR Build
Generates MIR for a
match
expression.The MIR that we generate for a match looks like this.
Borrow checker
Borrow checker handles these
Example
http://csclub.uwaterloo.ca/~a52arora/test_suite/mir_dump/match_mir.main.–––-.nll.0.mir
Generated MIR contains:
We gave two fake reads here one for checking for patterns in the
let
statement and the for the scrutinee in thematch
block.Possible solution
Personally I feel this solution might be a little far from being ideal because:
My thoughts
Assumption
Can we do something like
_1 = FakeRead(); _2 = CreateClosure(move _1)
or_2 = CreateClosure(FakeRead(_2))
Essentially we introduce a list of "mentioned" upvars/captures as Fake operands into the closure struct.
How do we do the capture analysis side of this?
ExprUseVisitor has a
fake_read
method, that is called on the pattern/match block scrutineeSome concerns:
Performance
Perf results after partial impl of use place builder everywhere
This is a bit interesting because we still would've converted the interned slice into a vector which would've required memory allocation and free etc.
We would also need to modify CFG to use PlaceBuilder which might affect perf all around the mir_build.
2021-01-15
Example that causes fake reads:
Right fix is to introduce
!
patterns, wherematch x { }
is shorthand for this:Example with closures, which we also don't want to compile:
problems with this exact formulation:
imprecise:
match x.y { }
it would still do a FakeRead ofx
improved version:
Foo::A
)match x { _ => { } }
,x
would not be captured, and therefore the match does not introduce a fake readmatch x { y => { } }
would introduce a fake read, becausex
is capturedAman's premeeting thoughts 2021-01-22
For any Place inside a closure that starts of a variable that was defined outside the closure, we have a place that looks like:
Now when we need to use this place inside a closure, we convert it to a capture index that represents an ancestor path to this Place being built.
Eg: If a closure captured
x.0.0.0
and we see a use ofx.0.0.0.2
we will convert it into_1.<capture_index>.2
In the case of
x.0.0
and since this isn't really captured the compiler ICEs.How do we represent this in terms of data structures?
Essentially we can either add these as capture indecies starting at index n. Where n is the size of the actual captures.
We want to prioritize the set of real captured before we try looking into the fake captures
If we do convert place builder into a Place made for fake capture we should maintain the PlaceBuilder such that when more projections are applied, we can at some point get a Place starting off an actual capture.
foo
what this would compile to in mir
goal
today (which fails)
how do we get to the goal
[x.0]
// is used to create upvars[x]
// not used to create upvarsp
in the fake read list, aFakeRead(p)
instructioClosure { ... }
aggregate where...
isupvar0: place_for_upvar0 ... upvarN: place_for_upvarN
(taken from the accesses list)let (a, _) = x
becausex
is an upvar with no captureanother example:
[x]
// is used to create upvars[x]
// not used to create upvarsp
in the fake read list, aFakeRead(p)
instructioClosure { ... }
aggregate where...
isupvar0: place_for_upvar0 ... upvarN: place_for_upvarN
(taken from the accesses list)let (a, _) = x
becausex
is an upvar with no capturefinal proposal
Foo::A
)let
is some placep
that begins with an upvar, you omit the fake readp
is in the fake read list for the enclosing closure