Struct rustc_mir::build::Builder
[−]
[src]
pub struct Builder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { // some fields omitted }
rustc_private
)Methods
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn ast_block(&mut self, destination: &Lvalue<'tcx>, dest_is_unit: bool, block: BasicBlock, ast_block: &'tcx Block) -> BlockAnd<()>
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn as_constant<M>(&mut self, expr: M) -> Constant<'tcx> where M: Mirror<'tcx, Output=Expr<'tcx>>
rustc_private
)Compile expr
, yielding a compile-time constant. Assumes that
expr
is a valid compile-time constant!
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn as_lvalue<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Lvalue<'tcx>> where M: Mirror<'tcx, Output=Expr<'tcx>>
rustc_private
)Compile expr
, yielding an lvalue that we can move from etc.
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn as_rvalue<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Rvalue<'tcx>> where M: Mirror<'tcx, Output=Expr<'tcx>>
rustc_private
)Compile expr
, yielding an rvalue.
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn as_operand<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Operand<'tcx>> where M: Mirror<'tcx, Output=Expr<'tcx>>
rustc_private
)Compile expr
into a value that can be used as an operand.
If expr
is an lvalue like x
, this will introduce a
temporary tmp = x
, so that we capture the value of x
at
this time.
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn as_temp<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Lvalue<'tcx>> where M: Mirror<'tcx, Output=Expr<'tcx>>
rustc_private
)Compile expr
into a fresh temporary. This is used when building
up rvalues so as to freeze the value that will be consumed.
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn into_expr(&mut self, destination: &Lvalue<'tcx>, block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd<()>
rustc_private
)Compile expr
, storing the result into destination
, which
is assumed to be uninitialized.
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn stmt_expr(&mut self, block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd<()>
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn into<E>(&mut self, destination: &Lvalue<'tcx>, block: BasicBlock, expr: E) -> BlockAnd<()> where E: EvalInto<'tcx>
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn simplify_candidate<'pat>(&mut self, block: BasicBlock, candidate: &mut Candidate<'pat, 'tcx>) -> BlockAnd<()>
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx>
rustc_private
)Identifies what test is needed to decide if match_pair
is applicable.
It is a bug to call this with a simplifyable pattern.
fn add_cases_to_switch<'pat>(&mut self, test_lvalue: &Lvalue<'tcx>, candidate: &Candidate<'pat, 'tcx>, switch_ty: Ty<'tcx>, options: &mut Vec<ConstVal>, indices: &mut FnvHashMap<ConstVal, usize>) -> bool
fn perform_test(&mut self, block: BasicBlock, lvalue: &Lvalue<'tcx>, test: &Test<'tcx>) -> Vec<BasicBlock>
rustc_private
)Generates the code to perform a test.
fn sort_candidate<'pat>(&mut self, test_lvalue: &Lvalue<'tcx>, test: &Test<'tcx>, candidate: &Candidate<'pat, 'tcx>, resulting_candidates: &mut [Vec<Candidate<'pat, 'tcx>>]) -> bool
rustc_private
)Given that we are performing test
against test_lvalue
,
this job sorts out what the status of candidate
will be
after the test. The resulting_candidates
vector stores, for
each possible outcome of test
, a vector of the candidates
that will result. This fn should add a (possibly modified)
clone of candidate into resulting_candidates
wherever
appropriate.
So, for example, if this candidate is x @ Some(P0)
and the
test is a variant test, then we would add (x as Option).0 @ P0
to the resulting_candidates
entry corresponding to the
variant Some
.
However, in some cases, the test may just not be relevant to
candidate. For example, suppose we are testing whether foo.x == 22
,
but in one match arm we have Foo { x: _, ... }
... in that case,
the test for what value x
has has no particular relevance
to this candidate. In such cases, this function just returns false
without doing anything. This is used by the overall match_candidates
algorithm to structure the match as a whole. See match_candidates
for
more details.
FIXME(#29623). In some cases, we have some tricky choices to
make. for example, if we are testing that x == 22
, but the
candidate is x @ 13..55
, what should we do? In the event
that the test is true, we know that the candidate applies, but
in the event of false, we don't know that it doesn't
apply. For now, we return false, indicate that the test does
not apply to this candidate, but it might be we can get
tighter match code if we do something a bit different.
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn field_match_pairs<'pat>(&mut self, lvalue: Lvalue<'tcx>, subpatterns: &'pat [FieldPattern<'tcx>]) -> Vec<MatchPair<'pat, 'tcx>>
fn prefix_suffix_slice<'pat>(&mut self, match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>, block: BasicBlock, lvalue: Lvalue<'tcx>, prefix: &'pat [Pattern<'tcx>], opt_slice: Option<&'pat Pattern<'tcx>>, suffix: &'pat [Pattern<'tcx>]) -> BlockAnd<()>
rustc_private
)When processing an array/slice pattern like lv @ [x, y, ..s, z]
,
this function converts the prefix (x
, y
) and suffix (z
) into
distinct match pairs:
lv[0 of 3] @ x // see ProjectionElem::ConstantIndex (and its Debug impl) lv[1 of 3] @ y // to explain the `[x of y]` notation lv[-1 of 3] @ z
If a slice like s
is present, then the function also creates
a temporary like:
tmp0 = lv[2..-1] // using the special Rvalue::Slice
and creates a match pair tmp0 @ s
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn match_expr(&mut self, destination: &Lvalue<'tcx>, span: Span, block: BasicBlock, discriminant: ExprRef<'tcx>, arms: Vec<Arm<'tcx>>) -> BlockAnd<()>
fn expr_into_pattern(&mut self, block: BasicBlock, var_scope_id: ScopeId, irrefutable_pat: Pattern<'tcx>, initializer: ExprRef<'tcx>) -> BlockAnd<()>
fn lvalue_into_pattern(&mut self, block: BasicBlock, var_scope_id: ScopeId, irrefutable_pat: Pattern<'tcx>, initializer: &Lvalue<'tcx>) -> BlockAnd<()>
fn declare_bindings(&mut self, var_scope_id: ScopeId, pattern: &Pattern<'tcx>)
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn temp(&mut self, ty: Ty<'tcx>) -> Lvalue<'tcx>
rustc_private
)Add a new temporary value of type ty
storing the result of
evaluating expr
.
NB: No cleanup is scheduled for this temporary. You should
call schedule_drop
once the temporary is initialized.
fn literal_operand(&mut self, span: Span, ty: Ty<'tcx>, literal: Literal<'tcx>) -> Operand<'tcx>
fn unit_rvalue(&mut self) -> Rvalue<'tcx>
fn push_usize(&mut self, block: BasicBlock, scope_id: ScopeId, span: Span, value: u64) -> Lvalue<'tcx>
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx>
[src]
fn in_loop_scope<F>(&mut self, loop_block: BasicBlock, break_block: BasicBlock, f: F) -> bool where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>)
rustc_private
)Start a loop scope, which tracks where continue
and break
should branch to. See module comment for more details.
Returns the might_break attribute of the LoopScope used.
fn in_scope<F, R>(&mut self, extent: CodeExtent, block: BasicBlock, f: F) -> BlockAnd<R> where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>, ScopeId) -> BlockAnd<R>
rustc_private
)Convenience wrapper that pushes a scope and then executes f
to build its contents, popping the scope afterwards.
fn push_scope(&mut self, extent: CodeExtent, entry: BasicBlock) -> ScopeId
rustc_private
)Push a scope onto the stack. You can then build code in this
scope and call pop_scope
afterwards. Note that these two
calls must be paired; using in_scope
as a convenience
wrapper maybe preferable.
fn pop_scope(&mut self, extent: CodeExtent, block: BasicBlock) -> BlockAnd<()>
rustc_private
)Pops a scope, which should have extent extent
, adding any
drops onto the end of block
that are needed. This must
match 1-to-1 with push_scope
.
fn exit_scope(&mut self, span: Span, extent: CodeExtent, block: BasicBlock, target: BasicBlock)
rustc_private
)Branch out of block
to target
, exiting all scopes up to
and including extent
. This will insert whatever drops are
needed, as well as tracking this exit for the SEME region. See
module comment for details.
fn find_loop_scope(&mut self, span: Span, label: Option<CodeExtent>) -> &mut LoopScope
rustc_private
)Finds the loop scope for a given label. This is used for
resolving break
and continue
.
fn innermost_scope_id(&self) -> ScopeId
fn extent_of_innermost_scope(&self) -> CodeExtent
fn extent_of_return_scope(&self) -> CodeExtent
rustc_private
)Returns the extent of the scope which should be exited by a return.
fn schedule_drop(&mut self, span: Span, extent: CodeExtent, lvalue: &Lvalue<'tcx>, lvalue_ty: Ty<'tcx>)
rustc_private
)Indicates that lvalue
should be dropped on exit from
extent
.
fn schedule_box_free(&mut self, span: Span, extent: CodeExtent, value: &Lvalue<'tcx>, item_ty: Ty<'tcx>)
rustc_private
)Schedule dropping of a not-yet-fully-initialised box.
This cleanup will only be translated into unwind branch.
The extent should be for the EXPR
inside box EXPR
.
There may only be one “free” scheduled in any given scope.
fn diverge_cleanup(&mut self) -> Option<BasicBlock>
rustc_private
)Creates a path that performs all required cleanup for unwinding.
This path terminates in Resume. Returns the start of the path. See module comment for more details. None indicates there’s no cleanup to do at this point.
fn build_drop(&mut self, block: BasicBlock, span: Span, value: Lvalue<'tcx>, ty: Ty<'tcx>) -> BlockAnd<()>
rustc_private
)Utility function for non-scope code to build their own drops
fn panic_bounds_check(&mut self, block: BasicBlock, index: Operand<'tcx>, len: Operand<'tcx>, span: Span)
fn panic(&mut self, block: BasicBlock, msg: &'static str, span: Span)
rustc_private
)Create diverge cleanup and branch to it from block
.