]> git.lizzy.rs Git - rust.git/commitdiff
Account for ADT bodies and struct expressions
authorEsteban Küber <esteban@kuber.com.ar>
Thu, 29 Dec 2022 02:26:59 +0000 (18:26 -0800)
committerEsteban Küber <esteban@kuber.com.ar>
Thu, 29 Dec 2022 02:30:18 +0000 (18:30 -0800)
12 files changed:
compiler/rustc_parse/src/parser/expr.rs
compiler/rustc_parse/src/parser/item.rs
src/test/ui/parser/diff-markers/enum-2.rs [new file with mode: 0644]
src/test/ui/parser/diff-markers/enum-2.stderr [new file with mode: 0644]
src/test/ui/parser/diff-markers/enum.rs [new file with mode: 0644]
src/test/ui/parser/diff-markers/enum.stderr [new file with mode: 0644]
src/test/ui/parser/diff-markers/struct-expr.rs [new file with mode: 0644]
src/test/ui/parser/diff-markers/struct-expr.stderr [new file with mode: 0644]
src/test/ui/parser/diff-markers/struct.rs [new file with mode: 0644]
src/test/ui/parser/diff-markers/struct.stderr [new file with mode: 0644]
src/test/ui/parser/diff-markers/tuple-struct.rs [new file with mode: 0644]
src/test/ui/parser/diff-markers/tuple-struct.stderr [new file with mode: 0644]

index 6a115088eca61803496212c69e4614b90cec6c31..1fc1ffd6cb6ed39e70463a7743fc48d8c9fabecd 100644 (file)
@@ -3039,6 +3039,7 @@ fn recover_struct_field_dots(&mut self, close_delim: Delimiter) -> bool {
     /// Parses `ident (COLON expr)?`.
     fn parse_expr_field(&mut self) -> PResult<'a, ExprField> {
         let attrs = self.parse_outer_attributes()?;
+        self.recover_diff_marker();
         self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
             let lo = this.token.span;
 
index 51de3d40d91348e4d06c02fd3c90bc63f7679485..b996ce0a15571737fdb3a757698650d1a6e15743 100644 (file)
@@ -1385,7 +1385,9 @@ fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
     }
 
     fn parse_enum_variant(&mut self) -> PResult<'a, Option<Variant>> {
+        self.recover_diff_marker();
         let variant_attrs = self.parse_outer_attributes()?;
+        self.recover_diff_marker();
         self.collect_tokens_trailing_token(
             variant_attrs,
             ForceCollect::No,
@@ -1579,9 +1581,32 @@ fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<FieldDef>> {
         self.parse_paren_comma_seq(|p| {
             let attrs = p.parse_outer_attributes()?;
             p.collect_tokens_trailing_token(attrs, ForceCollect::No, |p, attrs| {
+                let mut snapshot = None;
+                if p.is_diff_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) {
+                    // Account for `<<<<<<<` diff markers. We can't proactivelly error here because
+                    // that can be a valid type start, so we snapshot and reparse only we've
+                    // encountered another parse error.
+                    snapshot = Some(p.create_snapshot_for_diagnostic());
+                }
                 let lo = p.token.span;
-                let vis = p.parse_visibility(FollowedByType::Yes)?;
-                let ty = p.parse_ty()?;
+                let vis = match p.parse_visibility(FollowedByType::Yes) {
+                    Ok(vis) => vis,
+                    Err(err) => {
+                        if let Some(ref mut snapshot) = snapshot {
+                            snapshot.recover_diff_marker();
+                        }
+                        return Err(err);
+                    }
+                };
+                let ty = match p.parse_ty() {
+                    Ok(ty) => ty,
+                    Err(err) => {
+                        if let Some(ref mut snapshot) = snapshot {
+                            snapshot.recover_diff_marker();
+                        }
+                        return Err(err);
+                    }
+                };
 
                 Ok((
                     FieldDef {
@@ -1602,7 +1627,9 @@ fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<FieldDef>> {
 
     /// Parses an element of a struct declaration.
     fn parse_field_def(&mut self, adt_ty: &str) -> PResult<'a, FieldDef> {
+        self.recover_diff_marker();
         let attrs = self.parse_outer_attributes()?;
+        self.recover_diff_marker();
         self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
             let lo = this.token.span;
             let vis = this.parse_visibility(FollowedByType::No)?;
diff --git a/src/test/ui/parser/diff-markers/enum-2.rs b/src/test/ui/parser/diff-markers/enum-2.rs
new file mode 100644 (file)
index 0000000..d8c5272
--- /dev/null
@@ -0,0 +1,9 @@
+enum E {
+    Foo {
+<<<<<<< HEAD //~ ERROR encountered diff marker
+        x: u8,
+=======
+        x: i8,
+>>>>>>> branch
+    }
+}
diff --git a/src/test/ui/parser/diff-markers/enum-2.stderr b/src/test/ui/parser/diff-markers/enum-2.stderr
new file mode 100644 (file)
index 0000000..5264a59
--- /dev/null
@@ -0,0 +1,14 @@
+error: encountered diff marker
+  --> $DIR/enum-2.rs:3:1
+   |
+LL | <<<<<<< HEAD
+   | ^^^^^^^ start
+LL |         x: u8,
+LL | =======
+   | ^^^^^^^ middle
+LL |         x: i8,
+LL | >>>>>>> branch
+   | ^^^^^^^ end
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/diff-markers/enum.rs b/src/test/ui/parser/diff-markers/enum.rs
new file mode 100644 (file)
index 0000000..45df6e3
--- /dev/null
@@ -0,0 +1,7 @@
+enum E {
+<<<<<<< HEAD //~ ERROR encountered diff marker
+    Foo(u8),
+=======
+    Bar(i8),
+>>>>>>> branch
+}
diff --git a/src/test/ui/parser/diff-markers/enum.stderr b/src/test/ui/parser/diff-markers/enum.stderr
new file mode 100644 (file)
index 0000000..6bdc20d
--- /dev/null
@@ -0,0 +1,14 @@
+error: encountered diff marker
+  --> $DIR/enum.rs:2:1
+   |
+LL | <<<<<<< HEAD
+   | ^^^^^^^ start
+LL |     Foo(u8),
+LL | =======
+   | ^^^^^^^ middle
+LL |     Bar(i8),
+LL | >>>>>>> branch
+   | ^^^^^^^ end
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/diff-markers/struct-expr.rs b/src/test/ui/parser/diff-markers/struct-expr.rs
new file mode 100644 (file)
index 0000000..99d2fd6
--- /dev/null
@@ -0,0 +1,12 @@
+struct S {
+    x: u8,
+}
+fn main() {
+    let _ = S {
+<<<<<<< HEAD //~ ERROR encountered diff marker
+        x: 42,
+=======
+        x: 0,
+>>>>>>> branch
+    }
+}
diff --git a/src/test/ui/parser/diff-markers/struct-expr.stderr b/src/test/ui/parser/diff-markers/struct-expr.stderr
new file mode 100644 (file)
index 0000000..0ddb1a3
--- /dev/null
@@ -0,0 +1,14 @@
+error: encountered diff marker
+  --> $DIR/struct-expr.rs:6:1
+   |
+LL | <<<<<<< HEAD
+   | ^^^^^^^ start
+LL |         x: 42,
+LL | =======
+   | ^^^^^^^ middle
+LL |         x: 0,
+LL | >>>>>>> branch
+   | ^^^^^^^ end
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/diff-markers/struct.rs b/src/test/ui/parser/diff-markers/struct.rs
new file mode 100644 (file)
index 0000000..d26464d
--- /dev/null
@@ -0,0 +1,7 @@
+struct S {
+<<<<<<< HEAD //~ ERROR encountered diff marker
+    x: u8,
+=======
+    x: i8,
+>>>>>>> branch
+}
diff --git a/src/test/ui/parser/diff-markers/struct.stderr b/src/test/ui/parser/diff-markers/struct.stderr
new file mode 100644 (file)
index 0000000..e47bcfd
--- /dev/null
@@ -0,0 +1,14 @@
+error: encountered diff marker
+  --> $DIR/struct.rs:2:1
+   |
+LL | <<<<<<< HEAD
+   | ^^^^^^^ start
+LL |     x: u8,
+LL | =======
+   | ^^^^^^^ middle
+LL |     x: i8,
+LL | >>>>>>> branch
+   | ^^^^^^^ end
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/diff-markers/tuple-struct.rs b/src/test/ui/parser/diff-markers/tuple-struct.rs
new file mode 100644 (file)
index 0000000..7eec35c
--- /dev/null
@@ -0,0 +1,7 @@
+struct S(
+<<<<<<< HEAD //~ ERROR encountered diff marker
+    u8,
+=======
+    i8,
+>>>>>>> branch
+);
diff --git a/src/test/ui/parser/diff-markers/tuple-struct.stderr b/src/test/ui/parser/diff-markers/tuple-struct.stderr
new file mode 100644 (file)
index 0000000..7f30cbc
--- /dev/null
@@ -0,0 +1,14 @@
+error: encountered diff marker
+  --> $DIR/tuple-struct.rs:2:1
+   |
+LL | <<<<<<< HEAD
+   | ^^^^^^^ start
+LL |     u8,
+LL | =======
+   | ^^^^^^^ middle
+LL |     i8,
+LL | >>>>>>> branch
+   | ^^^^^^^ end
+
+error: aborting due to previous error
+