pub(crate) struct FixupContext {
stmt: bool,
leftmost_subexpression_in_stmt: bool,
match_arm: bool,
leftmost_subexpression_in_match_arm: bool,
parenthesize_exterior_struct_lit: bool,
}
Fields§
§stmt: bool
Print expression such that it can be parsed back as a statement consisting of the original expression.
The effect of this is for binary operators in statement position to set
leftmost_subexpression_in_stmt
when printing their left-hand operand.
(match x {}) - 1; // match needs parens when LHS of binary operator
match x {}; // not when its own statement
leftmost_subexpression_in_stmt: bool
This is the difference between:
(match x {}) - 1; // subexpression needs parens
let _ = match x {} - 1; // no parens
There are 3 distinguishable contexts in which print_expr
might be
called with the expression $match
as its argument, where $match
represents an expression of kind ExprKind::Match
:
-
stmt=false leftmost_subexpression_in_stmt=false
Example:
let _ = $match - 1;
No parentheses required.
-
stmt=false leftmost_subexpression_in_stmt=true
Example:
$match - 1;
Must parenthesize
($match)
, otherwise parsing back the output as a statement would terminate the statement after the closing brace of the match, parsing-1;
as a separate statement. -
stmt=true leftmost_subexpression_in_stmt=false
Example:
$match;
No parentheses required.
match_arm: bool
Print expression such that it can be parsed as a match arm.
This is almost equivalent to stmt
, but the grammar diverges a tiny bit
between statements and match arms when it comes to braced macro calls.
Macro calls with brace delimiter terminate a statement without a
semicolon, but do not terminate a match-arm without comma.
m! {} - 1; // two statements: a macro call followed by -1 literal
match () {
_ => m! {} - 1, // binary subtraction operator
}
leftmost_subexpression_in_match_arm: bool
This is almost equivalent to leftmost_subexpression_in_stmt
, other
than for braced macro calls.
If we have m! {} - 1
as an expression, the leftmost subexpression
m! {}
will need to be parenthesized in the statement case but not the
match-arm case.
(m! {}) - 1; // subexpression needs parens
match () {
_ => m! {} - 1, // no parens
}
parenthesize_exterior_struct_lit: bool
This is the difference between:
if let _ = (Struct {}) {} // needs parens
match () {
() if let _ = Struct {} => {} // no parens
}
Implementations§
source§impl FixupContext
impl FixupContext
sourcepub(crate) fn new_stmt() -> Self
pub(crate) fn new_stmt() -> Self
Create the initial fixup for printing an expression in statement position.
sourcepub(crate) fn new_match_arm() -> Self
pub(crate) fn new_match_arm() -> Self
Create the initial fixup for printing an expression as the right-hand side of a match arm.
sourcepub(crate) fn new_cond() -> Self
pub(crate) fn new_cond() -> Self
Create the initial fixup for printing an expression as the “condition”
of an if
or while
. There are a few other positions which are
grammatically equivalent and also use this, such as the iterator
expression in for
and the scrutinee in match
.
sourcepub(crate) fn leftmost_subexpression(self) -> Self
pub(crate) fn leftmost_subexpression(self) -> Self
Transform this fixup into the one that should apply when printing the leftmost subexpression of the current expression.
The leftmost subexpression is any subexpression that has the same first token as the current expression, but has a different last token.
For example in $a + $b
and $a.method()
, the subexpression $a
is a
leftmost subexpression.
Not every expression has a leftmost subexpression. For example neither
-$a
nor [$a]
have one.
sourcepub(crate) fn subsequent_subexpression(self) -> Self
pub(crate) fn subsequent_subexpression(self) -> Self
Transform this fixup into the one that should apply when printing any subexpression that is neither a leftmost subexpression nor surrounded in delimiters.
This is for any subexpression that has a different first token than the
current expression, and is not surrounded by a paren/bracket/brace. For
example the $b
in $a + $b
and -$b
, but not the one in [$b]
or
$a.f($b)
.
sourcepub(crate) fn would_cause_statement_boundary(self, expr: &Expr) -> bool
pub(crate) fn would_cause_statement_boundary(self, expr: &Expr) -> bool
Determine whether parentheses are needed around the given expression to head off an unintended statement boundary.
The documentation on FixupContext::leftmost_subexpression_in_stmt
has
examples.
sourcepub(crate) fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool
pub(crate) fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool
Determine whether parentheses are needed around the given let
scrutinee.
In if let _ = $e {}
, some examples of $e
that would need parentheses
are:
-
Struct {}.f()
, because otherwise the{
would be misinterpreted as the opening of the if’s then-block. -
true && false
, because otherwise this would be misinterpreted as a “let chain”.
Trait Implementations§
source§impl Clone for FixupContext
impl Clone for FixupContext
source§fn clone(&self) -> FixupContext
fn clone(&self) -> FixupContext
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl Debug for FixupContext
impl Debug for FixupContext
source§impl Default for FixupContext
impl Default for FixupContext
The default amount of fixing is minimal fixing. Fixups should be turned on in a targeted fashion where needed.
impl Copy for FixupContext
Auto Trait Implementations§
impl Freeze for FixupContext
impl RefUnwindSafe for FixupContext
impl Send for FixupContext
impl Sync for FixupContext
impl Unpin for FixupContext
impl UnwindSafe for FixupContext
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
source§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
impl<'a, T> Captures<'a> for Twhere
T: ?Sized,
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 5 bytes