diff options
| author | bors <bors@rust-lang.org> | 2019-03-26 17:25:16 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-03-26 17:25:16 +0000 |
| commit | fbd34efb32b9efb574899e4335bdc8c6525ac27e (patch) | |
| tree | 53ca160f6c731c05e092002bae40e03b22dae376 /src/libsyntax/parse | |
| parent | 07d350897c7f95bb40ae9762ad1e945f95fc37ae (diff) | |
| parent | 822b4fcb3bb583240c47158ee91d8ed6ae805e45 (diff) | |
| download | rust-fbd34efb32b9efb574899e4335bdc8c6525ac27e.tar.gz rust-fbd34efb32b9efb574899e4335bdc8c6525ac27e.zip | |
Auto merge of #59433 - Centril:rollup, r=Centril
Rollup of 10 pull requests
Successful merges:
- #59150 (Expand suggestions for type ascription parse errors)
- #59232 (Merge `Promoted` and `Static` in `mir::Place`)
- #59267 (Provide suggestion when using field access instead of path)
- #59315 (Add no_hash to query macro and move some queries over)
- #59334 (Update build instructions in README.md)
- #59362 (Demo `FromIterator` short-circuiting)
- #59374 (Simplify checked_duration_since)
- #59389 (replace redundant note in deprecation warning)
- #59410 (Clarify `{Ord,f32,f64}::clamp` docs a little)
- #59419 (Utilize `?` instead of `return None`.)
Failed merges:
r? @ghost
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 75 |
1 files changed, 62 insertions, 13 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d7a2170342d..a0c3fe35608 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3538,22 +3538,19 @@ impl<'a> Parser<'a> { lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?; continue } else if op == AssocOp::Colon { + let maybe_path = self.could_ascription_be_path(&lhs.node); + let next_sp = self.span; + lhs = match self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type) { Ok(lhs) => lhs, Err(mut err) => { - err.span_label(self.span, - "expecting a type here because of type ascription"); - let cm = self.sess.source_map(); - let cur_pos = cm.lookup_char_pos(self.span.lo()); - let op_pos = cm.lookup_char_pos(cur_op_span.hi()); - if cur_pos.line != op_pos.line { - err.span_suggestion( - cur_op_span, - "try using a semicolon", - ";".to_string(), - Applicability::MaybeIncorrect // speculative - ); - } + self.bad_type_ascription( + &mut err, + lhs_span, + cur_op_span, + next_sp, + maybe_path, + ); return Err(err); } }; @@ -3658,6 +3655,58 @@ impl<'a> Parser<'a> { Ok(lhs) } + fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool { + self.token.is_ident() && + if let ast::ExprKind::Path(..) = node { true } else { false } && + !self.token.is_reserved_ident() && // v `foo:bar(baz)` + self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) || + self.look_ahead(1, |t| t == &token::Lt) && // `foo:bar<baz` + self.look_ahead(2, |t| t.is_ident()) || + self.look_ahead(1, |t| t == &token::Colon) && // `foo:bar:baz` + self.look_ahead(2, |t| t.is_ident()) || + self.look_ahead(1, |t| t == &token::ModSep) && // `foo:bar::baz` + self.look_ahead(2, |t| t.is_ident()) + } + + fn bad_type_ascription( + &self, + err: &mut DiagnosticBuilder<'a>, + lhs_span: Span, + cur_op_span: Span, + next_sp: Span, + maybe_path: bool, + ) { + err.span_label(self.span, "expecting a type here because of type ascription"); + let cm = self.sess.source_map(); + let next_pos = cm.lookup_char_pos(next_sp.lo()); + let op_pos = cm.lookup_char_pos(cur_op_span.hi()); + if op_pos.line != next_pos.line { + err.span_suggestion( + cur_op_span, + "try using a semicolon", + ";".to_string(), + Applicability::MaybeIncorrect, + ); + } else { + if maybe_path { + err.span_suggestion( + cur_op_span, + "maybe you meant to write a path separator here", + "::".to_string(), + Applicability::MaybeIncorrect, + ); + } else { + err.note("type ascription is a nightly-only feature that lets \ + you annotate an expression with a type: `<expr>: <type>`"); + err.span_note( + lhs_span, + "this expression expects an ascribed type after the colon", + ); + err.help("this might be indicative of a syntax error elsewhere"); + } + } + } + fn parse_assoc_op_cast(&mut self, lhs: P<Expr>, lhs_span: Span, expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind) -> PResult<'a, P<Expr>> { |
