fixup.rs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. // SPDX-License-Identifier: Apache-2.0 OR MIT
  2. use crate::classify;
  3. use crate::expr::Expr;
  4. #[cfg(feature = "full")]
  5. use crate::expr::{
  6. ExprBreak, ExprRange, ExprRawAddr, ExprReference, ExprReturn, ExprUnary, ExprYield,
  7. };
  8. use crate::precedence::Precedence;
  9. #[cfg(feature = "full")]
  10. use crate::ty::ReturnType;
  11. pub(crate) struct FixupContext {
  12. #[cfg(feature = "full")]
  13. previous_operator: Precedence,
  14. #[cfg(feature = "full")]
  15. next_operator: Precedence,
  16. // Print expression such that it can be parsed back as a statement
  17. // consisting of the original expression.
  18. //
  19. // The effect of this is for binary operators in statement position to set
  20. // `leftmost_subexpression_in_stmt` when printing their left-hand operand.
  21. //
  22. // (match x {}) - 1; // match needs parens when LHS of binary operator
  23. //
  24. // match x {}; // not when its own statement
  25. //
  26. #[cfg(feature = "full")]
  27. stmt: bool,
  28. // This is the difference between:
  29. //
  30. // (match x {}) - 1; // subexpression needs parens
  31. //
  32. // let _ = match x {} - 1; // no parens
  33. //
  34. // There are 3 distinguishable contexts in which `print_expr` might be
  35. // called with the expression `$match` as its argument, where `$match`
  36. // represents an expression of kind `ExprKind::Match`:
  37. //
  38. // - stmt=false leftmost_subexpression_in_stmt=false
  39. //
  40. // Example: `let _ = $match - 1;`
  41. //
  42. // No parentheses required.
  43. //
  44. // - stmt=false leftmost_subexpression_in_stmt=true
  45. //
  46. // Example: `$match - 1;`
  47. //
  48. // Must parenthesize `($match)`, otherwise parsing back the output as a
  49. // statement would terminate the statement after the closing brace of
  50. // the match, parsing `-1;` as a separate statement.
  51. //
  52. // - stmt=true leftmost_subexpression_in_stmt=false
  53. //
  54. // Example: `$match;`
  55. //
  56. // No parentheses required.
  57. #[cfg(feature = "full")]
  58. leftmost_subexpression_in_stmt: bool,
  59. // Print expression such that it can be parsed as a match arm.
  60. //
  61. // This is almost equivalent to `stmt`, but the grammar diverges a tiny bit
  62. // between statements and match arms when it comes to braced macro calls.
  63. // Macro calls with brace delimiter terminate a statement without a
  64. // semicolon, but do not terminate a match-arm without comma.
  65. //
  66. // m! {} - 1; // two statements: a macro call followed by -1 literal
  67. //
  68. // match () {
  69. // _ => m! {} - 1, // binary subtraction operator
  70. // }
  71. //
  72. #[cfg(feature = "full")]
  73. match_arm: bool,
  74. // This is almost equivalent to `leftmost_subexpression_in_stmt`, other than
  75. // for braced macro calls.
  76. //
  77. // If we have `m! {} - 1` as an expression, the leftmost subexpression
  78. // `m! {}` will need to be parenthesized in the statement case but not the
  79. // match-arm case.
  80. //
  81. // (m! {}) - 1; // subexpression needs parens
  82. //
  83. // match () {
  84. // _ => m! {} - 1, // no parens
  85. // }
  86. //
  87. #[cfg(feature = "full")]
  88. leftmost_subexpression_in_match_arm: bool,
  89. // This is the difference between:
  90. //
  91. // if let _ = (Struct {}) {} // needs parens
  92. //
  93. // match () {
  94. // () if let _ = Struct {} => {} // no parens
  95. // }
  96. //
  97. #[cfg(feature = "full")]
  98. condition: bool,
  99. // This is the difference between:
  100. //
  101. // if break Struct {} == (break) {} // needs parens
  102. //
  103. // if break break == Struct {} {} // no parens
  104. //
  105. #[cfg(feature = "full")]
  106. rightmost_subexpression_in_condition: bool,
  107. // This is the difference between:
  108. //
  109. // if break ({ x }).field + 1 {} needs parens
  110. //
  111. // if break 1 + { x }.field {} // no parens
  112. //
  113. #[cfg(feature = "full")]
  114. leftmost_subexpression_in_optional_operand: bool,
  115. // This is the difference between:
  116. //
  117. // let _ = (return) - 1; // without paren, this would return -1
  118. //
  119. // let _ = return + 1; // no paren because '+' cannot begin expr
  120. //
  121. #[cfg(feature = "full")]
  122. next_operator_can_begin_expr: bool,
  123. // This is the difference between:
  124. //
  125. // let _ = 1 + return 1; // no parens if rightmost subexpression
  126. //
  127. // let _ = 1 + (return 1) + 1; // needs parens
  128. //
  129. #[cfg(feature = "full")]
  130. next_operator_can_continue_expr: bool,
  131. // This is the difference between:
  132. //
  133. // let _ = x as u8 + T;
  134. //
  135. // let _ = (x as u8) < T;
  136. //
  137. // Without parens, the latter would want to parse `u8<T...` as a type.
  138. next_operator_can_begin_generics: bool,
  139. }
  140. impl FixupContext {
  141. /// The default amount of fixing is minimal fixing. Fixups should be turned
  142. /// on in a targeted fashion where needed.
  143. pub const NONE: Self = FixupContext {
  144. #[cfg(feature = "full")]
  145. previous_operator: Precedence::MIN,
  146. #[cfg(feature = "full")]
  147. next_operator: Precedence::MIN,
  148. #[cfg(feature = "full")]
  149. stmt: false,
  150. #[cfg(feature = "full")]
  151. leftmost_subexpression_in_stmt: false,
  152. #[cfg(feature = "full")]
  153. match_arm: false,
  154. #[cfg(feature = "full")]
  155. leftmost_subexpression_in_match_arm: false,
  156. #[cfg(feature = "full")]
  157. condition: false,
  158. #[cfg(feature = "full")]
  159. rightmost_subexpression_in_condition: false,
  160. #[cfg(feature = "full")]
  161. leftmost_subexpression_in_optional_operand: false,
  162. #[cfg(feature = "full")]
  163. next_operator_can_begin_expr: false,
  164. #[cfg(feature = "full")]
  165. next_operator_can_continue_expr: false,
  166. next_operator_can_begin_generics: false,
  167. };
  168. /// Create the initial fixup for printing an expression in statement
  169. /// position.
  170. #[cfg(feature = "full")]
  171. pub fn new_stmt() -> Self {
  172. FixupContext {
  173. stmt: true,
  174. ..FixupContext::NONE
  175. }
  176. }
  177. /// Create the initial fixup for printing an expression as the right-hand
  178. /// side of a match arm.
  179. #[cfg(feature = "full")]
  180. pub fn new_match_arm() -> Self {
  181. FixupContext {
  182. match_arm: true,
  183. ..FixupContext::NONE
  184. }
  185. }
  186. /// Create the initial fixup for printing an expression as the "condition"
  187. /// of an `if` or `while`. There are a few other positions which are
  188. /// grammatically equivalent and also use this, such as the iterator
  189. /// expression in `for` and the scrutinee in `match`.
  190. #[cfg(feature = "full")]
  191. pub fn new_condition() -> Self {
  192. FixupContext {
  193. condition: true,
  194. rightmost_subexpression_in_condition: true,
  195. ..FixupContext::NONE
  196. }
  197. }
  198. /// Transform this fixup into the one that should apply when printing the
  199. /// leftmost subexpression of the current expression.
  200. ///
  201. /// The leftmost subexpression is any subexpression that has the same first
  202. /// token as the current expression, but has a different last token.
  203. ///
  204. /// For example in `$a + $b` and `$a.method()`, the subexpression `$a` is a
  205. /// leftmost subexpression.
  206. ///
  207. /// Not every expression has a leftmost subexpression. For example neither
  208. /// `-$a` nor `[$a]` have one.
  209. pub fn leftmost_subexpression_with_operator(
  210. self,
  211. expr: &Expr,
  212. #[cfg(feature = "full")] next_operator_can_begin_expr: bool,
  213. next_operator_can_begin_generics: bool,
  214. #[cfg(feature = "full")] precedence: Precedence,
  215. ) -> (Precedence, Self) {
  216. let fixup = FixupContext {
  217. #[cfg(feature = "full")]
  218. next_operator: precedence,
  219. #[cfg(feature = "full")]
  220. stmt: false,
  221. #[cfg(feature = "full")]
  222. leftmost_subexpression_in_stmt: self.stmt || self.leftmost_subexpression_in_stmt,
  223. #[cfg(feature = "full")]
  224. match_arm: false,
  225. #[cfg(feature = "full")]
  226. leftmost_subexpression_in_match_arm: self.match_arm
  227. || self.leftmost_subexpression_in_match_arm,
  228. #[cfg(feature = "full")]
  229. rightmost_subexpression_in_condition: false,
  230. #[cfg(feature = "full")]
  231. next_operator_can_begin_expr,
  232. #[cfg(feature = "full")]
  233. next_operator_can_continue_expr: true,
  234. next_operator_can_begin_generics,
  235. ..self
  236. };
  237. (fixup.leftmost_subexpression_precedence(expr), fixup)
  238. }
  239. /// Transform this fixup into the one that should apply when printing a
  240. /// leftmost subexpression followed by a `.` or `?` token, which confer
  241. /// different statement boundary rules compared to other leftmost
  242. /// subexpressions.
  243. pub fn leftmost_subexpression_with_dot(self, expr: &Expr) -> (Precedence, Self) {
  244. let fixup = FixupContext {
  245. #[cfg(feature = "full")]
  246. next_operator: Precedence::Unambiguous,
  247. #[cfg(feature = "full")]
  248. stmt: self.stmt || self.leftmost_subexpression_in_stmt,
  249. #[cfg(feature = "full")]
  250. leftmost_subexpression_in_stmt: false,
  251. #[cfg(feature = "full")]
  252. match_arm: self.match_arm || self.leftmost_subexpression_in_match_arm,
  253. #[cfg(feature = "full")]
  254. leftmost_subexpression_in_match_arm: false,
  255. #[cfg(feature = "full")]
  256. rightmost_subexpression_in_condition: false,
  257. #[cfg(feature = "full")]
  258. next_operator_can_begin_expr: false,
  259. #[cfg(feature = "full")]
  260. next_operator_can_continue_expr: true,
  261. next_operator_can_begin_generics: false,
  262. ..self
  263. };
  264. (fixup.leftmost_subexpression_precedence(expr), fixup)
  265. }
  266. fn leftmost_subexpression_precedence(self, expr: &Expr) -> Precedence {
  267. #[cfg(feature = "full")]
  268. if !self.next_operator_can_begin_expr || self.next_operator == Precedence::Range {
  269. if let Scan::Bailout = scan_right(expr, self, Precedence::MIN, 0, 0) {
  270. if scan_left(expr, self) {
  271. return Precedence::Unambiguous;
  272. }
  273. }
  274. }
  275. self.precedence(expr)
  276. }
  277. /// Transform this fixup into the one that should apply when printing the
  278. /// rightmost subexpression of the current expression.
  279. ///
  280. /// The rightmost subexpression is any subexpression that has a different
  281. /// first token than the current expression, but has the same last token.
  282. ///
  283. /// For example in `$a + $b` and `-$b`, the subexpression `$b` is a
  284. /// rightmost subexpression.
  285. ///
  286. /// Not every expression has a rightmost subexpression. For example neither
  287. /// `[$b]` nor `$a.f($b)` have one.
  288. pub fn rightmost_subexpression(
  289. self,
  290. expr: &Expr,
  291. #[cfg(feature = "full")] precedence: Precedence,
  292. ) -> (Precedence, Self) {
  293. let fixup = self.rightmost_subexpression_fixup(
  294. #[cfg(feature = "full")]
  295. false,
  296. #[cfg(feature = "full")]
  297. false,
  298. #[cfg(feature = "full")]
  299. precedence,
  300. );
  301. (fixup.rightmost_subexpression_precedence(expr), fixup)
  302. }
  303. pub fn rightmost_subexpression_fixup(
  304. self,
  305. #[cfg(feature = "full")] reset_allow_struct: bool,
  306. #[cfg(feature = "full")] optional_operand: bool,
  307. #[cfg(feature = "full")] precedence: Precedence,
  308. ) -> Self {
  309. FixupContext {
  310. #[cfg(feature = "full")]
  311. previous_operator: precedence,
  312. #[cfg(feature = "full")]
  313. stmt: false,
  314. #[cfg(feature = "full")]
  315. leftmost_subexpression_in_stmt: false,
  316. #[cfg(feature = "full")]
  317. match_arm: false,
  318. #[cfg(feature = "full")]
  319. leftmost_subexpression_in_match_arm: false,
  320. #[cfg(feature = "full")]
  321. condition: self.condition && !reset_allow_struct,
  322. #[cfg(feature = "full")]
  323. leftmost_subexpression_in_optional_operand: self.condition && optional_operand,
  324. ..self
  325. }
  326. }
  327. pub fn rightmost_subexpression_precedence(self, expr: &Expr) -> Precedence {
  328. let default_prec = self.precedence(expr);
  329. #[cfg(feature = "full")]
  330. if match self.previous_operator {
  331. Precedence::Assign | Precedence::Let | Precedence::Prefix => {
  332. default_prec < self.previous_operator
  333. }
  334. _ => default_prec <= self.previous_operator,
  335. } && match self.next_operator {
  336. Precedence::Range | Precedence::Or | Precedence::And => true,
  337. _ => !self.next_operator_can_begin_expr,
  338. } {
  339. if let Scan::Bailout | Scan::Fail = scan_right(expr, self, self.previous_operator, 1, 0)
  340. {
  341. if scan_left(expr, self) {
  342. return Precedence::Prefix;
  343. }
  344. }
  345. }
  346. default_prec
  347. }
  348. /// Determine whether parentheses are needed around the given expression to
  349. /// head off the early termination of a statement or condition.
  350. #[cfg(feature = "full")]
  351. pub fn parenthesize(self, expr: &Expr) -> bool {
  352. (self.leftmost_subexpression_in_stmt && !classify::requires_semi_to_be_stmt(expr))
  353. || ((self.stmt || self.leftmost_subexpression_in_stmt) && matches!(expr, Expr::Let(_)))
  354. || (self.leftmost_subexpression_in_match_arm
  355. && !classify::requires_comma_to_be_match_arm(expr))
  356. || (self.condition && matches!(expr, Expr::Struct(_)))
  357. || (self.rightmost_subexpression_in_condition
  358. && matches!(
  359. expr,
  360. Expr::Return(ExprReturn { expr: None, .. })
  361. | Expr::Yield(ExprYield { expr: None, .. })
  362. ))
  363. || (self.rightmost_subexpression_in_condition
  364. && !self.condition
  365. && matches!(
  366. expr,
  367. Expr::Break(ExprBreak { expr: None, .. })
  368. | Expr::Path(_)
  369. | Expr::Range(ExprRange { end: None, .. })
  370. ))
  371. || (self.leftmost_subexpression_in_optional_operand
  372. && matches!(expr, Expr::Block(expr) if expr.attrs.is_empty() && expr.label.is_none()))
  373. }
  374. /// Determines the effective precedence of a subexpression. Some expressions
  375. /// have higher or lower precedence when adjacent to particular operators.
  376. fn precedence(self, expr: &Expr) -> Precedence {
  377. #[cfg(feature = "full")]
  378. if self.next_operator_can_begin_expr {
  379. // Decrease precedence of value-less jumps when followed by an
  380. // operator that would otherwise get interpreted as beginning a
  381. // value for the jump.
  382. if let Expr::Break(ExprBreak { expr: None, .. })
  383. | Expr::Return(ExprReturn { expr: None, .. })
  384. | Expr::Yield(ExprYield { expr: None, .. }) = expr
  385. {
  386. return Precedence::Jump;
  387. }
  388. }
  389. #[cfg(feature = "full")]
  390. if !self.next_operator_can_continue_expr {
  391. match expr {
  392. // Increase precedence of expressions that extend to the end of
  393. // current statement or group.
  394. Expr::Break(_)
  395. | Expr::Closure(_)
  396. | Expr::Let(_)
  397. | Expr::Return(_)
  398. | Expr::Yield(_) => {
  399. return Precedence::Prefix;
  400. }
  401. Expr::Range(e) if e.start.is_none() => return Precedence::Prefix,
  402. _ => {}
  403. }
  404. }
  405. if self.next_operator_can_begin_generics {
  406. if let Expr::Cast(cast) = expr {
  407. if classify::trailing_unparameterized_path(&cast.ty) {
  408. return Precedence::MIN;
  409. }
  410. }
  411. }
  412. Precedence::of(expr)
  413. }
  414. }
  415. impl Copy for FixupContext {}
  416. impl Clone for FixupContext {
  417. fn clone(&self) -> Self {
  418. *self
  419. }
  420. }
  421. #[cfg(feature = "full")]
  422. enum Scan {
  423. Fail,
  424. Bailout,
  425. Consume,
  426. }
  427. #[cfg(feature = "full")]
  428. impl Copy for Scan {}
  429. #[cfg(feature = "full")]
  430. impl Clone for Scan {
  431. fn clone(&self) -> Self {
  432. *self
  433. }
  434. }
  435. #[cfg(feature = "full")]
  436. impl PartialEq for Scan {
  437. fn eq(&self, other: &Self) -> bool {
  438. *self as u8 == *other as u8
  439. }
  440. }
  441. #[cfg(feature = "full")]
  442. fn scan_left(expr: &Expr, fixup: FixupContext) -> bool {
  443. match expr {
  444. Expr::Assign(_) => fixup.previous_operator <= Precedence::Assign,
  445. Expr::Binary(e) => match Precedence::of_binop(&e.op) {
  446. Precedence::Assign => fixup.previous_operator <= Precedence::Assign,
  447. binop_prec => fixup.previous_operator < binop_prec,
  448. },
  449. Expr::Cast(_) => fixup.previous_operator < Precedence::Cast,
  450. Expr::Range(e) => e.start.is_none() || fixup.previous_operator < Precedence::Assign,
  451. _ => true,
  452. }
  453. }
  454. #[cfg(feature = "full")]
  455. fn scan_right(
  456. expr: &Expr,
  457. fixup: FixupContext,
  458. precedence: Precedence,
  459. fail_offset: u8,
  460. bailout_offset: u8,
  461. ) -> Scan {
  462. let consume_by_precedence = if match precedence {
  463. Precedence::Assign | Precedence::Compare => precedence <= fixup.next_operator,
  464. _ => precedence < fixup.next_operator,
  465. } || fixup.next_operator == Precedence::MIN
  466. {
  467. Scan::Consume
  468. } else {
  469. Scan::Bailout
  470. };
  471. if fixup.parenthesize(expr) {
  472. return consume_by_precedence;
  473. }
  474. match expr {
  475. Expr::Assign(e) if e.attrs.is_empty() => {
  476. if match fixup.next_operator {
  477. Precedence::Unambiguous => fail_offset >= 2,
  478. _ => bailout_offset >= 1,
  479. } {
  480. return Scan::Consume;
  481. }
  482. let right_fixup = fixup.rightmost_subexpression_fixup(false, false, Precedence::Assign);
  483. let scan = scan_right(
  484. &e.right,
  485. right_fixup,
  486. Precedence::Assign,
  487. match fixup.next_operator {
  488. Precedence::Unambiguous => fail_offset,
  489. _ => 1,
  490. },
  491. 1,
  492. );
  493. if let Scan::Bailout | Scan::Consume = scan {
  494. Scan::Consume
  495. } else if let Precedence::Unambiguous = fixup.next_operator {
  496. Scan::Fail
  497. } else {
  498. Scan::Bailout
  499. }
  500. }
  501. Expr::Binary(e) if e.attrs.is_empty() => {
  502. if match fixup.next_operator {
  503. Precedence::Unambiguous => {
  504. fail_offset >= 2
  505. && (consume_by_precedence == Scan::Consume || bailout_offset >= 1)
  506. }
  507. _ => bailout_offset >= 1,
  508. } {
  509. return Scan::Consume;
  510. }
  511. let binop_prec = Precedence::of_binop(&e.op);
  512. if binop_prec == Precedence::Compare && fixup.next_operator == Precedence::Compare {
  513. return Scan::Consume;
  514. }
  515. let right_fixup = fixup.rightmost_subexpression_fixup(false, false, binop_prec);
  516. let scan = scan_right(
  517. &e.right,
  518. right_fixup,
  519. binop_prec,
  520. match fixup.next_operator {
  521. Precedence::Unambiguous => fail_offset,
  522. _ => 1,
  523. },
  524. consume_by_precedence as u8 - Scan::Bailout as u8,
  525. );
  526. match scan {
  527. Scan::Fail => {}
  528. Scan::Bailout => return consume_by_precedence,
  529. Scan::Consume => return Scan::Consume,
  530. }
  531. let right_needs_group = binop_prec != Precedence::Assign
  532. && right_fixup.rightmost_subexpression_precedence(&e.right) <= binop_prec;
  533. if right_needs_group {
  534. consume_by_precedence
  535. } else if let (Scan::Fail, Precedence::Unambiguous) = (scan, fixup.next_operator) {
  536. Scan::Fail
  537. } else {
  538. Scan::Bailout
  539. }
  540. }
  541. Expr::RawAddr(ExprRawAddr { expr, .. })
  542. | Expr::Reference(ExprReference { expr, .. })
  543. | Expr::Unary(ExprUnary { expr, .. }) => {
  544. if match fixup.next_operator {
  545. Precedence::Unambiguous => {
  546. fail_offset >= 2
  547. && (consume_by_precedence == Scan::Consume || bailout_offset >= 1)
  548. }
  549. _ => bailout_offset >= 1,
  550. } {
  551. return Scan::Consume;
  552. }
  553. let right_fixup = fixup.rightmost_subexpression_fixup(false, false, Precedence::Prefix);
  554. let scan = scan_right(
  555. expr,
  556. right_fixup,
  557. precedence,
  558. match fixup.next_operator {
  559. Precedence::Unambiguous => fail_offset,
  560. _ => 1,
  561. },
  562. consume_by_precedence as u8 - Scan::Bailout as u8,
  563. );
  564. match scan {
  565. Scan::Fail => {}
  566. Scan::Bailout => return consume_by_precedence,
  567. Scan::Consume => return Scan::Consume,
  568. }
  569. if right_fixup.rightmost_subexpression_precedence(expr) < Precedence::Prefix {
  570. consume_by_precedence
  571. } else if let (Scan::Fail, Precedence::Unambiguous) = (scan, fixup.next_operator) {
  572. Scan::Fail
  573. } else {
  574. Scan::Bailout
  575. }
  576. }
  577. Expr::Range(e) if e.attrs.is_empty() => match &e.end {
  578. Some(end) => {
  579. if fail_offset >= 2 {
  580. return Scan::Consume;
  581. }
  582. let right_fixup =
  583. fixup.rightmost_subexpression_fixup(false, true, Precedence::Range);
  584. let scan = scan_right(
  585. end,
  586. right_fixup,
  587. Precedence::Range,
  588. fail_offset,
  589. match fixup.next_operator {
  590. Precedence::Assign | Precedence::Range => 0,
  591. _ => 1,
  592. },
  593. );
  594. if match (scan, fixup.next_operator) {
  595. (Scan::Fail, _) => false,
  596. (Scan::Bailout, Precedence::Assign | Precedence::Range) => false,
  597. (Scan::Bailout | Scan::Consume, _) => true,
  598. } {
  599. return Scan::Consume;
  600. }
  601. if right_fixup.rightmost_subexpression_precedence(end) <= Precedence::Range {
  602. Scan::Consume
  603. } else {
  604. Scan::Fail
  605. }
  606. }
  607. None => {
  608. if fixup.next_operator_can_begin_expr {
  609. Scan::Consume
  610. } else {
  611. Scan::Fail
  612. }
  613. }
  614. },
  615. Expr::Break(e) => match &e.expr {
  616. Some(value) => {
  617. if bailout_offset >= 1 || e.label.is_none() && classify::expr_leading_label(value) {
  618. return Scan::Consume;
  619. }
  620. let right_fixup = fixup.rightmost_subexpression_fixup(true, true, Precedence::Jump);
  621. match scan_right(value, right_fixup, Precedence::Jump, 1, 1) {
  622. Scan::Fail => Scan::Bailout,
  623. Scan::Bailout | Scan::Consume => Scan::Consume,
  624. }
  625. }
  626. None => match fixup.next_operator {
  627. Precedence::Assign if precedence > Precedence::Assign => Scan::Fail,
  628. _ => Scan::Consume,
  629. },
  630. },
  631. Expr::Return(ExprReturn { expr, .. }) | Expr::Yield(ExprYield { expr, .. }) => match expr {
  632. Some(e) => {
  633. if bailout_offset >= 1 {
  634. return Scan::Consume;
  635. }
  636. let right_fixup =
  637. fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump);
  638. match scan_right(e, right_fixup, Precedence::Jump, 1, 1) {
  639. Scan::Fail => Scan::Bailout,
  640. Scan::Bailout | Scan::Consume => Scan::Consume,
  641. }
  642. }
  643. None => match fixup.next_operator {
  644. Precedence::Assign if precedence > Precedence::Assign => Scan::Fail,
  645. _ => Scan::Consume,
  646. },
  647. },
  648. Expr::Closure(e) => {
  649. if matches!(e.output, ReturnType::Default)
  650. || matches!(&*e.body, Expr::Block(body) if body.attrs.is_empty() && body.label.is_none())
  651. {
  652. if bailout_offset >= 1 {
  653. return Scan::Consume;
  654. }
  655. let right_fixup =
  656. fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump);
  657. match scan_right(&e.body, right_fixup, Precedence::Jump, 1, 1) {
  658. Scan::Fail => Scan::Bailout,
  659. Scan::Bailout | Scan::Consume => Scan::Consume,
  660. }
  661. } else {
  662. Scan::Consume
  663. }
  664. }
  665. Expr::Let(e) => {
  666. if bailout_offset >= 1 {
  667. return Scan::Consume;
  668. }
  669. let right_fixup = fixup.rightmost_subexpression_fixup(false, false, Precedence::Let);
  670. let scan = scan_right(
  671. &e.expr,
  672. right_fixup,
  673. Precedence::Let,
  674. 1,
  675. if fixup.next_operator < Precedence::Let {
  676. 0
  677. } else {
  678. 1
  679. },
  680. );
  681. match scan {
  682. Scan::Fail | Scan::Bailout if fixup.next_operator < Precedence::Let => {
  683. return Scan::Bailout;
  684. }
  685. Scan::Consume => return Scan::Consume,
  686. _ => {}
  687. }
  688. if right_fixup.rightmost_subexpression_precedence(&e.expr) < Precedence::Let {
  689. Scan::Consume
  690. } else if let Scan::Fail = scan {
  691. Scan::Bailout
  692. } else {
  693. Scan::Consume
  694. }
  695. }
  696. Expr::Array(_)
  697. | Expr::Assign(_)
  698. | Expr::Async(_)
  699. | Expr::Await(_)
  700. | Expr::Binary(_)
  701. | Expr::Block(_)
  702. | Expr::Call(_)
  703. | Expr::Cast(_)
  704. | Expr::Const(_)
  705. | Expr::Continue(_)
  706. | Expr::Field(_)
  707. | Expr::ForLoop(_)
  708. | Expr::Group(_)
  709. | Expr::If(_)
  710. | Expr::Index(_)
  711. | Expr::Infer(_)
  712. | Expr::Lit(_)
  713. | Expr::Loop(_)
  714. | Expr::Macro(_)
  715. | Expr::Match(_)
  716. | Expr::MethodCall(_)
  717. | Expr::Paren(_)
  718. | Expr::Path(_)
  719. | Expr::Range(_)
  720. | Expr::Repeat(_)
  721. | Expr::Struct(_)
  722. | Expr::Try(_)
  723. | Expr::TryBlock(_)
  724. | Expr::Tuple(_)
  725. | Expr::Unsafe(_)
  726. | Expr::Verbatim(_)
  727. | Expr::While(_) => match fixup.next_operator {
  728. Precedence::Assign | Precedence::Range if precedence == Precedence::Range => Scan::Fail,
  729. _ if precedence == Precedence::Let && fixup.next_operator < Precedence::Let => {
  730. Scan::Fail
  731. }
  732. _ => consume_by_precedence,
  733. },
  734. }
  735. }