about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-07-08 04:05:41 +0000
committerbors <bors@rust-lang.org>2021-07-08 04:05:41 +0000
commitac8c3bfffb2829d0af075a5d4020fb7e9e86c3a2 (patch)
tree7ed177e41caaf762288a5e899f18a027fa12e320 /compiler/rustc_parse/src/parser
parentd2b04f075c0ce010758c4c8674152ff89d1d73f3 (diff)
parent01474ad92cc025ac7e16a9d70c76c2d030d414d7 (diff)
downloadrust-ac8c3bfffb2829d0af075a5d4020fb7e9e86c3a2.tar.gz
rust-ac8c3bfffb2829d0af075a5d4020fb7e9e86c3a2.zip
Auto merge of #86966 - JohnTitor:rollup-uiqj2vc, r=JohnTitor
Rollup of 9 pull requests

Successful merges:

 - #86639 (Support lint tool names in rustc command line options)
 - #86812 (Recover from `&dyn mut ...` parse errors)
 - #86917 (Add doc comment for `impl From<LayoutError> for TryReserveError`)
 - #86925 (Add self to mailmap)
 - #86927 (Sync rustc_codegen_cranelift)
 - #86932 (Fix ICE when misplaced visibility cannot be properly parsed)
 - #86933 (Clean up rustdoc static files)
 - #86955 (Fix typo in `ops::Drop` docs)
 - #86956 (Revert "Add "every" as a doc alias for "all".")

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/item.rs8
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs22
2 files changed, 28 insertions, 2 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 2daa9e2485b..2ce63d011f4 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1791,7 +1791,13 @@ impl<'a> Parser<'a> {
                     if self.check_keyword(kw::Pub) {
                         let sp = sp_start.to(self.prev_token.span);
                         if let Ok(snippet) = self.span_to_snippet(sp) {
-                            let vis = self.parse_visibility(FollowedByType::No)?;
+                            let vis = match self.parse_visibility(FollowedByType::No) {
+                                Ok(v) => v,
+                                Err(mut d) => {
+                                    d.cancel();
+                                    return Err(err);
+                                }
+                            };
                             let vs = pprust::vis_to_string(&vis);
                             let vs = vs.trim_end();
                             err.span_suggestion(
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index de5a5632600..1fbf01b1b97 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -393,7 +393,7 @@ impl<'a> Parser<'a> {
         let and_span = self.prev_token.span;
         let mut opt_lifetime =
             if self.check_lifetime() { Some(self.expect_lifetime()) } else { None };
-        let mutbl = self.parse_mutability();
+        let mut mutbl = self.parse_mutability();
         if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
             // A lifetime is invalid here: it would be part of a bare trait bound, which requires
             // it to be followed by a plus, but we disallow plus in the pointee type.
@@ -417,6 +417,26 @@ impl<'a> Parser<'a> {
 
                 opt_lifetime = Some(self.expect_lifetime());
             }
+        } else if self.token.is_keyword(kw::Dyn)
+            && mutbl == Mutability::Not
+            && self.look_ahead(1, |t| t.is_keyword(kw::Mut))
+        {
+            // We have `&dyn mut ...`, which is invalid and should be `&mut dyn ...`.
+            let span = and_span.to(self.look_ahead(1, |t| t.span));
+            let mut err = self.struct_span_err(span, "`mut` must precede `dyn`");
+            err.span_suggestion(
+                span,
+                "place `mut` before `dyn`",
+                "&mut dyn".to_string(),
+                Applicability::MachineApplicable,
+            );
+            err.emit();
+
+            // Recovery
+            mutbl = Mutability::Mut;
+            let (dyn_tok, dyn_tok_sp) = (self.token.clone(), self.token_spacing);
+            self.bump();
+            self.bump_with((dyn_tok, dyn_tok_sp));
         }
         let ty = self.parse_ty_no_plus()?;
         Ok(TyKind::Rptr(opt_lifetime, MutTy { ty, mutbl }))