diff options
| author | bors <bors@rust-lang.org> | 2021-12-02 21:58:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-12-02 21:58:48 +0000 |
| commit | ff23ad3179014ba258f2b540fb39dd0f26852b7a (patch) | |
| tree | 205abbf762b77c2afb3e449dc31783eed1b58c00 /compiler/rustc_parse/src/parser | |
| parent | acbe4443cc4c9695c0b74a7b64b60333c990a400 (diff) | |
| parent | f7afd461c7a1e9431a3ce46c23bc7ccd233faa99 (diff) | |
| download | rust-ff23ad3179014ba258f2b540fb39dd0f26852b7a.tar.gz rust-ff23ad3179014ba258f2b540fb39dd0f26852b7a.zip | |
Auto merge of #91469 - matthiaskrgr:rollup-xom3j55, r=matthiaskrgr
Rollup of 12 pull requests Successful merges: - #89954 (Fix legacy_const_generic doc arguments display) - #91321 (Handle placeholder regions in NLL type outlive constraints) - #91329 (Fix incorrect usage of `EvaluatedToOk` when evaluating `TypeOutlives`) - #91364 (Improve error message for incorrect field accesses through raw pointers) - #91387 (Clarify and tidy up explanation of E0038) - #91410 (Move `#![feature(const_precise_live_drops)]` checks earlier in the pipeline) - #91435 (Improve diagnostic for missing half of binary operator in `if` condition) - #91444 (disable tests in Miri that take too long) - #91457 (Add additional test from rust issue number 91068) - #91460 (Document how `last_os_error` should be used) - #91464 (Document file path case sensitivity) - #91466 (Improve the comments in `Symbol::interner`.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index f7ee874c831..1dbd7bad0f0 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1988,25 +1988,34 @@ impl<'a> Parser<'a> { let lo = self.prev_token.span; let cond = self.parse_cond_expr()?; + let missing_then_block_binop_span = || { + match cond.kind { + ExprKind::Binary(Spanned { span: binop_span, .. }, _, ref right) + if let ExprKind::Block(..) = right.kind => Some(binop_span), + _ => None + } + }; + // Verify that the parsed `if` condition makes sense as a condition. If it is a block, then // verify that the last statement is either an implicit return (no `;`) or an explicit // return. This won't catch blocks with an explicit `return`, but that would be caught by // the dead code lint. - let thn = if self.eat_keyword(kw::Else) || !cond.returns() { - self.error_missing_if_cond(lo, cond.span) + let thn = if self.token.is_keyword(kw::Else) || !cond.returns() { + if let Some(binop_span) = missing_then_block_binop_span() { + self.error_missing_if_then_block(lo, None, Some(binop_span)).emit(); + self.mk_block_err(cond.span) + } else { + self.error_missing_if_cond(lo, cond.span) + } } else { let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery. let not_block = self.token != token::OpenDelim(token::Brace); - let block = self.parse_block().map_err(|mut err| { + let block = self.parse_block().map_err(|err| { if not_block { - err.span_label(lo, "this `if` expression has a condition, but no block"); - if let ExprKind::Binary(_, _, ref right) = cond.kind { - if let ExprKind::Block(_, _) = right.kind { - err.help("maybe you forgot the right operand of the condition?"); - } - } + self.error_missing_if_then_block(lo, Some(err), missing_then_block_binop_span()) + } else { + err } - err })?; self.error_on_if_block_attrs(lo, false, block.span, &attrs); block @@ -2015,6 +2024,28 @@ impl<'a> Parser<'a> { Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::If(cond, thn, els), attrs)) } + fn error_missing_if_then_block( + &self, + if_span: Span, + err: Option<DiagnosticBuilder<'a>>, + binop_span: Option<Span>, + ) -> DiagnosticBuilder<'a> { + let msg = "this `if` expression has a condition, but no block"; + + let mut err = if let Some(mut err) = err { + err.span_label(if_span, msg); + err + } else { + self.struct_span_err(if_span, msg) + }; + + if let Some(binop_span) = binop_span { + err.span_help(binop_span, "maybe you forgot the right operand of the condition?"); + } + + err + } + fn error_missing_if_cond(&self, lo: Span, span: Span) -> P<ast::Block> { let sp = self.sess.source_map().next_point(lo); self.struct_span_err(sp, "missing condition for `if` expression") |
