about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-12-04 02:53:54 +0000
committerbors <bors@rust-lang.org>2021-12-04 02:53:54 +0000
commitf5815727786aa1ed2793af05cf65c5d79c290c67 (patch)
tree5c31934526b8f1a635e3212d45937ddffef49d10 /src
parent14c1e71d095a5500def51d4e405bd2b0010f3d37 (diff)
parentdf51bffe6bef0c15f6e29a15ea54f269b251e179 (diff)
downloadrust-f5815727786aa1ed2793af05cf65c5d79c290c67.tar.gz
rust-f5815727786aa1ed2793af05cf65c5d79c290c67.zip
Auto merge of #91505 - matthiaskrgr:rollup-orxgsxo, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #90538 (Document how recursion is handled for `ty::Ty`)
 - #90851 (Add unchecked downcast methods)
 - #91209 (Implement ``@snapshot`` check for htmldocck)
 - #91385 (Suggest the `pat_param` specifier before `|` on 2021 edition )
 - #91478 (Remove incorrect newline from float cast suggestion)
 - #91481 (Use let_else in some more places in rustc_lint)
 - #91488 (Fix ICE when `yield`ing in function returning `impl Trait`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src')
-rw-r--r--src/etc/htmldocck.py80
-rw-r--r--src/test/rustdoc/mixing-doc-comments-and-attrs.S1_top-doc.html4
-rw-r--r--src/test/rustdoc/mixing-doc-comments-and-attrs.S2_top-doc.html4
-rw-r--r--src/test/rustdoc/mixing-doc-comments-and-attrs.rs12
-rw-r--r--src/test/ui/generator/issue-91477.rs7
-rw-r--r--src/test/ui/generator/issue-91477.stderr9
-rw-r--r--src/test/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr12
-rw-r--r--src/test/ui/macros/macro-pat2021-pattern-followed-by-or.stderr12
-rw-r--r--src/test/ui/numeric/numeric-cast.stderr20
-rw-r--r--src/tools/compiletest/src/runtest.rs12
10 files changed, 136 insertions, 36 deletions
diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py
index 8647db5a45d..48a341ffe08 100644
--- a/src/etc/htmldocck.py
+++ b/src/etc/htmldocck.py
@@ -90,10 +90,20 @@ There are a number of supported commands:
   highlights for example. If you want to simply check for the presence of
   a given node or attribute, use an empty string (`""`) as a `PATTERN`.
 
-* `@count PATH XPATH COUNT' checks for the occurrence of the given XPath
+* `@count PATH XPATH COUNT` checks for the occurrence of the given XPath
   in the specified file. The number of occurrences must match the given
   count.
 
+* `@snapshot NAME PATH XPATH` creates a snapshot test named NAME.
+  A snapshot test captures a subtree of the DOM, at the location
+  determined by the XPath, and compares it to a pre-recorded value
+  in a file. The file's name is the test's name with the `.rs` extension
+  replaced with `.NAME.html`, where NAME is the snapshot's name.
+
+  htmldocck supports the `--bless` option to accept the current subtree
+  as expected, saving it to the file determined by the snapshot's name.
+  compiletest's `--bless` flag is forwarded to htmldocck.
+
 * `@has-dir PATH` checks for the existence of the given directory.
 
 All conditions can be negated with `!`. `@!has foo/type.NoSuch.html`
@@ -137,6 +147,10 @@ except NameError:
 
 channel = os.environ["DOC_RUST_LANG_ORG_CHANNEL"]
 
+# Initialized in main
+rust_test_path = None
+bless = None
+
 class CustomHTMLParser(HTMLParser):
     """simplified HTML parser.
 
@@ -387,6 +401,32 @@ def get_tree_count(tree, path):
     return len(tree.findall(path))
 
 
+def check_snapshot(snapshot_name, tree):
+    assert rust_test_path.endswith('.rs')
+    snapshot_path = '{}.{}.{}'.format(rust_test_path[:-3], snapshot_name, 'html')
+    try:
+        with open(snapshot_path, 'r') as snapshot_file:
+            expected_str = snapshot_file.read()
+    except FileNotFoundError:
+        if bless:
+            expected_str = None
+        else:
+            raise FailedCheck('No saved snapshot value')
+
+    actual_str = ET.tostring(tree).decode('utf-8')
+
+    if expected_str != actual_str:
+        if bless:
+            with open(snapshot_path, 'w') as snapshot_file:
+                snapshot_file.write(actual_str)
+        else:
+            print('--- expected ---\n')
+            print(expected_str)
+            print('\n\n--- actual ---\n')
+            print(actual_str)
+            print()
+            raise FailedCheck('Actual snapshot value is different than expected')
+
 def stderr(*args):
     if sys.version_info.major < 3:
         file = codecs.getwriter('utf-8')(sys.stderr)
@@ -448,6 +488,28 @@ def check_command(c, cache):
                 ret = expected == found
             else:
                 raise InvalidCheck('Invalid number of @{} arguments'.format(c.cmd))
+
+        elif c.cmd == 'snapshot':  # snapshot test
+            if len(c.args) == 3:  # @snapshot <snapshot-name> <html-path> <xpath>
+                [snapshot_name, html_path, pattern] = c.args
+                tree = cache.get_tree(html_path)
+                xpath = normalize_xpath(pattern)
+                subtrees = tree.findall(xpath)
+                if len(subtrees) == 1:
+                    [subtree] = subtrees
+                    try:
+                        check_snapshot(snapshot_name, subtree)
+                        ret = True
+                    except FailedCheck as err:
+                        cerr = str(err)
+                        ret = False
+                elif len(subtrees) == 0:
+                    raise FailedCheck('XPATH did not match')
+                else:
+                    raise FailedCheck('Expected 1 match, but found {}'.format(len(subtrees)))
+            else:
+                raise InvalidCheck('Invalid number of @{} arguments'.format(c.cmd))
+
         elif c.cmd == 'has-dir':  # has-dir test
             if len(c.args) == 1:  # @has-dir <path> = has-dir test
                 try:
@@ -458,11 +520,13 @@ def check_command(c, cache):
                     ret = False
             else:
                 raise InvalidCheck('Invalid number of @{} arguments'.format(c.cmd))
+
         elif c.cmd == 'valid-html':
             raise InvalidCheck('Unimplemented @valid-html')
 
         elif c.cmd == 'valid-links':
             raise InvalidCheck('Unimplemented @valid-links')
+
         else:
             raise InvalidCheck('Unrecognized @{}'.format(c.cmd))
 
@@ -483,11 +547,19 @@ def check(target, commands):
 
 
 if __name__ == '__main__':
-    if len(sys.argv) != 3:
-        stderr('Usage: {} <doc dir> <template>'.format(sys.argv[0]))
+    if len(sys.argv) not in [3, 4]:
+        stderr('Usage: {} <doc dir> <template> [--bless]'.format(sys.argv[0]))
         raise SystemExit(1)
 
-    check(sys.argv[1], get_commands(sys.argv[2]))
+    rust_test_path = sys.argv[2]
+    if len(sys.argv) > 3 and sys.argv[3] == '--bless':
+        bless = True
+    else:
+        # We only support `--bless` at the end of the arguments.
+        # This assert is to prevent silent failures.
+        assert '--bless' not in sys.argv
+        bless = False
+    check(sys.argv[1], get_commands(rust_test_path))
     if ERR_COUNT:
         stderr("\nEncountered {} errors".format(ERR_COUNT))
         raise SystemExit(1)
diff --git a/src/test/rustdoc/mixing-doc-comments-and-attrs.S1_top-doc.html b/src/test/rustdoc/mixing-doc-comments-and-attrs.S1_top-doc.html
new file mode 100644
index 00000000000..69d647a92e8
--- /dev/null
+++ b/src/test/rustdoc/mixing-doc-comments-and-attrs.S1_top-doc.html
@@ -0,0 +1,4 @@
+<div class="docblock"><p>Hello world!
+Goodbye!
+Hello again!</p>
+</div>
\ No newline at end of file
diff --git a/src/test/rustdoc/mixing-doc-comments-and-attrs.S2_top-doc.html b/src/test/rustdoc/mixing-doc-comments-and-attrs.S2_top-doc.html
new file mode 100644
index 00000000000..8ff114b993e
--- /dev/null
+++ b/src/test/rustdoc/mixing-doc-comments-and-attrs.S2_top-doc.html
@@ -0,0 +1,4 @@
+<div class="docblock"><p>Hello world!</p>
+<p>Goodbye!
+Hello again!</p>
+</div>
\ No newline at end of file
diff --git a/src/test/rustdoc/mixing-doc-comments-and-attrs.rs b/src/test/rustdoc/mixing-doc-comments-and-attrs.rs
index c26d3a31987..1aedd4d107c 100644
--- a/src/test/rustdoc/mixing-doc-comments-and-attrs.rs
+++ b/src/test/rustdoc/mixing-doc-comments-and-attrs.rs
@@ -1,10 +1,7 @@
 #![crate_name = "foo"]
 
 // @has 'foo/struct.S1.html'
-// @count - '//details[@class="rustdoc-toggle top-doc"]/div[@class="docblock"]/p' \
-//     1
-// @has - '//details[@class="rustdoc-toggle top-doc"]/div[@class="docblock"]/p[1]' \
-//     'Hello world! Goodbye! Hello again!'
+// @snapshot S1_top-doc - '//details[@class="rustdoc-toggle top-doc"]/div[@class="docblock"]'
 
 #[doc = "Hello world!\n\n"]
 /// Goodbye!
@@ -12,12 +9,7 @@
 pub struct S1;
 
 // @has 'foo/struct.S2.html'
-// @count - '//details[@class="rustdoc-toggle top-doc"]/div[@class="docblock"]/p' \
-//     2
-// @has - '//details[@class="rustdoc-toggle top-doc"]/div[@class="docblock"]/p[1]' \
-//     'Hello world!'
-// @has - '//details[@class="rustdoc-toggle top-doc"]/div[@class="docblock"]/p[2]' \
-//     'Goodbye! Hello again!'
+// @snapshot S2_top-doc - '//details[@class="rustdoc-toggle top-doc"]/div[@class="docblock"]'
 
 /// Hello world!
 ///
diff --git a/src/test/ui/generator/issue-91477.rs b/src/test/ui/generator/issue-91477.rs
new file mode 100644
index 00000000000..6c027feb422
--- /dev/null
+++ b/src/test/ui/generator/issue-91477.rs
@@ -0,0 +1,7 @@
+#![feature(generators)]
+
+fn foo() -> impl Sized {
+    yield 1; //~ ERROR E0627
+}
+
+fn main() {}
diff --git a/src/test/ui/generator/issue-91477.stderr b/src/test/ui/generator/issue-91477.stderr
new file mode 100644
index 00000000000..4597dc1bcdf
--- /dev/null
+++ b/src/test/ui/generator/issue-91477.stderr
@@ -0,0 +1,9 @@
+error[E0627]: yield expression outside of generator literal
+  --> $DIR/issue-91477.rs:4:5
+   |
+LL |     yield 1;
+   |     ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0627`.
diff --git a/src/test/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr b/src/test/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr
index a5987a25551..a06487be3d6 100644
--- a/src/test/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr
+++ b/src/test/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr
@@ -2,7 +2,9 @@ error: `$x:pat` is followed by `|`, which is not allowed for `pat` fragments
   --> $DIR/macro-pat-pattern-followed-by-or-in-2021.rs:3:28
    |
 LL | macro_rules! foo { ($x:pat | $y:pat) => {} }
-   |                            ^ not allowed after `pat` fragments
+   |                     ------ ^ not allowed after `pat` fragments
+   |                     |
+   |                     help: try a `pat_param` fragment specifier instead: `$x:pat_param`
    |
    = note: allowed there are: `=>`, `,`, `=`, `if` or `in`
 
@@ -10,7 +12,9 @@ error: `$x:pat` is followed by `|`, which is not allowed for `pat` fragments
   --> $DIR/macro-pat-pattern-followed-by-or-in-2021.rs:4:32
    |
 LL | macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} }
-   |                                ^ not allowed after `pat` fragments
+   |                       ------   ^ not allowed after `pat` fragments
+   |                       |
+   |                       help: try a `pat_param` fragment specifier instead: `$x:pat_param`
    |
    = note: allowed there are: `=>`, `,`, `=`, `if` or `in`
 
@@ -18,7 +22,9 @@ error: `$pat:pat` may be followed by `|`, which is not allowed for `pat` fragmen
   --> $DIR/macro-pat-pattern-followed-by-or-in-2021.rs:7:36
    |
 LL |     ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => {
-   |                                    ^ not allowed after `pat` fragments
+   |                          --------  ^ not allowed after `pat` fragments
+   |                          |
+   |                          help: try a `pat_param` fragment specifier instead: `$pat:pat_param`
    |
    = note: allowed there are: `=>`, `,`, `=`, `if` or `in`
 
diff --git a/src/test/ui/macros/macro-pat2021-pattern-followed-by-or.stderr b/src/test/ui/macros/macro-pat2021-pattern-followed-by-or.stderr
index 8aebe98515f..c3754dde080 100644
--- a/src/test/ui/macros/macro-pat2021-pattern-followed-by-or.stderr
+++ b/src/test/ui/macros/macro-pat2021-pattern-followed-by-or.stderr
@@ -2,7 +2,9 @@ error: `$x:pat` is followed by `|`, which is not allowed for `pat` fragments
   --> $DIR/macro-pat2021-pattern-followed-by-or.rs:4:28
    |
 LL | macro_rules! foo { ($x:pat | $y:pat) => {} }
-   |                            ^ not allowed after `pat` fragments
+   |                     ------ ^ not allowed after `pat` fragments
+   |                     |
+   |                     help: try a `pat_param` fragment specifier instead: `$x:pat_param`
    |
    = note: allowed there are: `=>`, `,`, `=`, `if` or `in`
 
@@ -10,7 +12,9 @@ error: `$x:pat` is followed by `|`, which is not allowed for `pat` fragments
   --> $DIR/macro-pat2021-pattern-followed-by-or.rs:7:28
    |
 LL | macro_rules! ogg { ($x:pat | $y:pat_param) => {} }
-   |                            ^ not allowed after `pat` fragments
+   |                     ------ ^ not allowed after `pat` fragments
+   |                     |
+   |                     help: try a `pat_param` fragment specifier instead: `$x:pat_param`
    |
    = note: allowed there are: `=>`, `,`, `=`, `if` or `in`
 
@@ -18,7 +22,9 @@ error: `$pat:pat` may be followed by `|`, which is not allowed for `pat` fragmen
   --> $DIR/macro-pat2021-pattern-followed-by-or.rs:9:35
    |
 LL |     ( $expr:expr , $( $( $pat:pat)|+ => $expr_arm:pat),+ ) => {
-   |                                   ^ not allowed after `pat` fragments
+   |                          -------- ^ not allowed after `pat` fragments
+   |                          |
+   |                          help: try a `pat_param` fragment specifier instead: `$pat:pat_param`
    |
    = note: allowed there are: `=>`, `,`, `=`, `if` or `in`
 
diff --git a/src/test/ui/numeric/numeric-cast.stderr b/src/test/ui/numeric/numeric-cast.stderr
index 3e2bc5bc82d..b8f2d88ab49 100644
--- a/src/test/ui/numeric/numeric-cast.stderr
+++ b/src/test/ui/numeric/numeric-cast.stderr
@@ -994,8 +994,8 @@ error[E0308]: mismatched types
 LL |     foo::<f64>(x_usize);
    |                ^^^^^^^ expected `f64`, found `usize`
    |
-help: you can cast a `usize` to an `f64`, producing the floating point representation of the integer,
-   |                                              rounded if necessary
+help: you can cast a `usize` to an `f64`, producing the floating point representation of the integer, rounded if necessary
+   |
 LL |     foo::<f64>(x_usize as f64);
    |                        ++++++
 
@@ -1005,8 +1005,8 @@ error[E0308]: mismatched types
 LL |     foo::<f64>(x_u64);
    |                ^^^^^ expected `f64`, found `u64`
    |
-help: you can cast a `u64` to an `f64`, producing the floating point representation of the integer,
-   |                                              rounded if necessary
+help: you can cast a `u64` to an `f64`, producing the floating point representation of the integer, rounded if necessary
+   |
 LL |     foo::<f64>(x_u64 as f64);
    |                      ++++++
 
@@ -1115,8 +1115,8 @@ error[E0308]: mismatched types
 LL |     foo::<f32>(x_usize);
    |                ^^^^^^^ expected `f32`, found `usize`
    |
-help: you can cast a `usize` to an `f32`, producing the floating point representation of the integer,
-   |                                              rounded if necessary
+help: you can cast a `usize` to an `f32`, producing the floating point representation of the integer, rounded if necessary
+   |
 LL |     foo::<f32>(x_usize as f32);
    |                        ++++++
 
@@ -1126,8 +1126,8 @@ error[E0308]: mismatched types
 LL |     foo::<f32>(x_u64);
    |                ^^^^^ expected `f32`, found `u64`
    |
-help: you can cast a `u64` to an `f32`, producing the floating point representation of the integer,
-   |                                              rounded if necessary
+help: you can cast a `u64` to an `f32`, producing the floating point representation of the integer, rounded if necessary
+   |
 LL |     foo::<f32>(x_u64 as f32);
    |                      ++++++
 
@@ -1137,8 +1137,8 @@ error[E0308]: mismatched types
 LL |     foo::<f32>(x_u32);
    |                ^^^^^ expected `f32`, found `u32`
    |
-help: you can cast a `u32` to an `f32`, producing the floating point representation of the integer,
-   |                                              rounded if necessary
+help: you can cast a `u32` to an `f32`, producing the floating point representation of the integer, rounded if necessary
+   |
 LL |     foo::<f32>(x_u32 as f32);
    |                      ++++++
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 727eecbb732..4bf74c1508b 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2219,12 +2219,12 @@ impl<'test> TestCx<'test> {
             self.check_rustdoc_test_option(proc_res);
         } else {
             let root = self.config.find_rust_src_root().unwrap();
-            let res = self.cmd2procres(
-                Command::new(&self.config.docck_python)
-                    .arg(root.join("src/etc/htmldocck.py"))
-                    .arg(&out_dir)
-                    .arg(&self.testpaths.file),
-            );
+            let mut cmd = Command::new(&self.config.docck_python);
+            cmd.arg(root.join("src/etc/htmldocck.py")).arg(&out_dir).arg(&self.testpaths.file);
+            if self.config.bless {
+                cmd.arg("--bless");
+            }
+            let res = self.cmd2procres(&mut cmd);
             if !res.status.success() {
                 self.fatal_proc_rec_with_ctx("htmldocck failed!", &res, |mut this| {
                     this.compare_to_default_rustdoc(&out_dir)