From 1d287255f57a6d42a44035ceb9861e96dfc5ee55 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Thu, 15 Oct 2020 14:03:39 -0700 Subject: [PATCH 01/11] Change mention of `fnv` in HashMap to mention `aHash` as an alternitive hasher. Signed-off-by: Tom Kaitchuck --- library/std/src/collections/hash/map.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 114707b639bce..0d8313c430e5f 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -35,7 +35,7 @@ use crate::sys; /// /// The hashing algorithm can be replaced on a per-`HashMap` basis using the /// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. Many -/// alternative algorithms are available on crates.io, such as the [`fnv`] crate. +/// alternative algorithms are available on crates.io, such as the [`aHash`] crate. /// /// It is required that the keys implement the [`Eq`] and [`Hash`] traits, although /// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`. @@ -154,7 +154,7 @@ use crate::sys; /// [`default`]: Default::default /// [`with_hasher`]: Self::with_hasher /// [`with_capacity_and_hasher`]: Self::with_capacity_and_hasher -/// [`fnv`]: https://crates.io/crates/fnv +/// [`aHash`]: https://crates.io/crates/ahash /// /// ``` /// use std::collections::HashMap; From 5b3d98d9f8d50a4bb3adf071dc6592cf458afbf1 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Tue, 27 Oct 2020 20:49:52 -0700 Subject: [PATCH 02/11] Change link to point to crates.io keyword "hasher" Signed-off-by: Tom Kaitchuck --- library/std/src/collections/hash/map.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 0d8313c430e5f..03d8b11a51aef 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -34,8 +34,8 @@ use crate::sys; /// attacks such as HashDoS. /// /// The hashing algorithm can be replaced on a per-`HashMap` basis using the -/// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. Many -/// alternative algorithms are available on crates.io, such as the [`aHash`] crate. +/// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. +/// There are many alternative [hashing algorithms available on crates.io]. /// /// It is required that the keys implement the [`Eq`] and [`Hash`] traits, although /// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`. @@ -57,6 +57,7 @@ use crate::sys; /// The original C++ version of SwissTable can be found [here], and this /// [CppCon talk] gives an overview of how the algorithm works. /// +/// [hashing algorithms available on crates.io]: https://crates.io/keywords/hasher /// [SwissTable]: https://abseil.io/blog/20180927-swisstables /// [here]: https://github.com/abseil/abseil-cpp/blob/master/absl/container/internal/raw_hash_set.h /// [CppCon talk]: https://www.youtube.com/watch?v=ncHmEUmJZf4 @@ -154,7 +155,6 @@ use crate::sys; /// [`default`]: Default::default /// [`with_hasher`]: Self::with_hasher /// [`with_capacity_and_hasher`]: Self::with_capacity_and_hasher -/// [`aHash`]: https://crates.io/crates/ahash /// /// ``` /// use std::collections::HashMap; From e8bda8defce426bae9caad1af7defebf88a24169 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Thu, 24 Sep 2020 17:25:48 +0200 Subject: [PATCH 03/11] Add regression test for issue #76042 --- src/test/ui/issues/issue-76042.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/test/ui/issues/issue-76042.rs diff --git a/src/test/ui/issues/issue-76042.rs b/src/test/ui/issues/issue-76042.rs new file mode 100644 index 0000000000000..34d5293799aa7 --- /dev/null +++ b/src/test/ui/issues/issue-76042.rs @@ -0,0 +1,16 @@ +// run-pass +// compile-flags: -Coverflow-checks=off -Ccodegen-units=1 -Copt-level=0 + +fn foo(a: i128, b: i128, s: u32) -> (i128, i128) { + if s == 128 { + (0, 0) + } else { + (b >> s, a >> s) + } +} +fn main() { + let r = foo(0, 8, 1); + if r.0 != 4 { + panic!(); + } +} From a51b13042e48c40a87597496fac01dc605aca55d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 12 Nov 2020 14:57:44 +0100 Subject: [PATCH 04/11] Add --check option to rustdoc --- src/librustdoc/config.rs | 6 ++++++ src/librustdoc/lib.rs | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 02885f519363c..c248d57a9ddf4 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -145,6 +145,9 @@ pub struct Options { pub render_options: RenderOptions, /// Output format rendering (used only for "show-coverage" option for the moment) pub output_format: Option, + /// If this option is set to `true`, rustdoc will only run checks and not generate + /// documentation. + pub run_check: bool, } impl fmt::Debug for Options { @@ -185,6 +188,7 @@ impl fmt::Debug for Options { .field("runtool", &self.runtool) .field("runtool_args", &self.runtool_args) .field("enable-per-target-ignores", &self.enable_per_target_ignores) + .field("run_check", &self.run_check) .finish() } } @@ -581,6 +585,7 @@ impl Options { let enable_per_target_ignores = matches.opt_present("enable-per-target-ignores"); let document_private = matches.opt_present("document-private-items"); let document_hidden = matches.opt_present("document-hidden-items"); + let run_check = matches.opt_present("check"); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); @@ -616,6 +621,7 @@ impl Options { runtool_args, enable_per_target_ignores, test_builder, + run_check, render_options: RenderOptions { output, external_html, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 7efbca5c6c3b7..d23c722e78edf 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -423,6 +423,7 @@ fn opts() -> Vec { "specified the rustc-like binary to use as the test builder", ) }), + unstable("check", |o| o.optflag("", "check", "Run rustdoc checks")), ] } @@ -514,6 +515,7 @@ fn main_options(options: config::Options) -> MainResult { // but we can't crates the Handler ahead of time because it's not Send let diag_opts = (options.error_format, options.edition, options.debugging_opts.clone()); let show_coverage = options.show_coverage; + let run_check = options.run_check; // First, parse the crate and extract all relevant information. info!("starting to run rustc"); @@ -539,6 +541,9 @@ fn main_options(options: config::Options) -> MainResult { // if we ran coverage, bail early, we don't need to also generate docs at this point // (also we didn't load in any of the useful passes) return Ok(()); + } else if run_check { + // Since we're in "check" mode, no need to generate anything beyond this point. + return Ok(()); } info!("going to format"); From 5e154fae925792096b11a6f6f30fc80f7362a6cf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 12 Nov 2020 14:58:07 +0100 Subject: [PATCH 05/11] Add tests for rustdoc --check option --- src/test/rustdoc-ui/check-fail.rs | 10 ++++++ src/test/rustdoc-ui/check-fail.stderr | 49 +++++++++++++++++++++++++++ src/test/rustdoc-ui/check.rs | 11 ++++++ src/test/rustdoc-ui/check.stderr | 49 +++++++++++++++++++++++++++ src/test/rustdoc/check.rs | 5 +++ 5 files changed, 124 insertions(+) create mode 100644 src/test/rustdoc-ui/check-fail.rs create mode 100644 src/test/rustdoc-ui/check-fail.stderr create mode 100644 src/test/rustdoc-ui/check.rs create mode 100644 src/test/rustdoc-ui/check.stderr create mode 100644 src/test/rustdoc/check.rs diff --git a/src/test/rustdoc-ui/check-fail.rs b/src/test/rustdoc-ui/check-fail.rs new file mode 100644 index 0000000000000..ccc9d24c1595a --- /dev/null +++ b/src/test/rustdoc-ui/check-fail.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z unstable-options --check + +#![deny(missing_docs)] +//~^ ERROR +//~^^ ERROR +#![deny(rustdoc)] + +pub fn foo() {} +//~^ ERROR +//~^^ ERROR diff --git a/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr new file mode 100644 index 0000000000000..979b2292f609b --- /dev/null +++ b/src/test/rustdoc-ui/check-fail.stderr @@ -0,0 +1,49 @@ +error: missing documentation for the crate + --> $DIR/check-fail.rs:3:1 + | +LL | / #![deny(missing_docs)] +LL | | +LL | | +LL | | #![deny(rustdoc)] +LL | | +LL | | pub fn foo() {} + | |_______________^ + | +note: the lint level is defined here + --> $DIR/check-fail.rs:3:9 + | +LL | #![deny(missing_docs)] + | ^^^^^^^^^^^^ + +error: missing documentation for a function + --> $DIR/check-fail.rs:8:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/check-fail.rs:3:1 + | +LL | / #![deny(missing_docs)] +LL | | +LL | | +LL | | #![deny(rustdoc)] +LL | | +LL | | pub fn foo() {} + | |_______________^ + | +note: the lint level is defined here + --> $DIR/check-fail.rs:6:9 + | +LL | #![deny(rustdoc)] + | ^^^^^^^ + = note: `#[deny(missing_doc_code_examples)]` implied by `#[deny(rustdoc)]` + +error: missing code example in this documentation + --> $DIR/check-fail.rs:8:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/rustdoc-ui/check.rs b/src/test/rustdoc-ui/check.rs new file mode 100644 index 0000000000000..022c56214d451 --- /dev/null +++ b/src/test/rustdoc-ui/check.rs @@ -0,0 +1,11 @@ +// check-pass +// compile-flags: -Z unstable-options --check + +#![warn(missing_docs)] +//~^ WARN +//~^^ WARN +#![warn(rustdoc)] + +pub fn foo() {} +//~^ WARN +//~^^ WARN diff --git a/src/test/rustdoc-ui/check.stderr b/src/test/rustdoc-ui/check.stderr new file mode 100644 index 0000000000000..27e5a736148e1 --- /dev/null +++ b/src/test/rustdoc-ui/check.stderr @@ -0,0 +1,49 @@ +warning: missing documentation for the crate + --> $DIR/check.rs:4:1 + | +LL | / #![warn(missing_docs)] +LL | | +LL | | +LL | | #![warn(rustdoc)] +LL | | +LL | | pub fn foo() {} + | |_______________^ + | +note: the lint level is defined here + --> $DIR/check.rs:4:9 + | +LL | #![warn(missing_docs)] + | ^^^^^^^^^^^^ + +warning: missing documentation for a function + --> $DIR/check.rs:9:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^ + +warning: missing code example in this documentation + --> $DIR/check.rs:4:1 + | +LL | / #![warn(missing_docs)] +LL | | +LL | | +LL | | #![warn(rustdoc)] +LL | | +LL | | pub fn foo() {} + | |_______________^ + | +note: the lint level is defined here + --> $DIR/check.rs:7:9 + | +LL | #![warn(rustdoc)] + | ^^^^^^^ + = note: `#[warn(missing_doc_code_examples)]` implied by `#[warn(rustdoc)]` + +warning: missing code example in this documentation + --> $DIR/check.rs:9:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted + diff --git a/src/test/rustdoc/check.rs b/src/test/rustdoc/check.rs new file mode 100644 index 0000000000000..1fb4b35ddbe86 --- /dev/null +++ b/src/test/rustdoc/check.rs @@ -0,0 +1,5 @@ +// compile-flags: -Z unstable-options --check + +// @!has check/fn.foo.html +// @!has check/index.html +pub fn foo() {} From 3539259795a6f1f5fa6c2ccb8fe1fb5b12af6e59 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 12 Nov 2020 15:31:52 +0100 Subject: [PATCH 06/11] move dropck tests from ui -> ui/dropck --- src/test/ui/{issues => dropck}/issue-38868.rs | 0 src/test/ui/{issues => dropck}/issue-38868.stderr | 0 src/test/ui/{ => dropck}/reject-specialized-drops-8142.rs | 0 src/test/ui/{ => dropck}/reject-specialized-drops-8142.stderr | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/{issues => dropck}/issue-38868.rs (100%) rename src/test/ui/{issues => dropck}/issue-38868.stderr (100%) rename src/test/ui/{ => dropck}/reject-specialized-drops-8142.rs (100%) rename src/test/ui/{ => dropck}/reject-specialized-drops-8142.stderr (100%) diff --git a/src/test/ui/issues/issue-38868.rs b/src/test/ui/dropck/issue-38868.rs similarity index 100% rename from src/test/ui/issues/issue-38868.rs rename to src/test/ui/dropck/issue-38868.rs diff --git a/src/test/ui/issues/issue-38868.stderr b/src/test/ui/dropck/issue-38868.stderr similarity index 100% rename from src/test/ui/issues/issue-38868.stderr rename to src/test/ui/dropck/issue-38868.stderr diff --git a/src/test/ui/reject-specialized-drops-8142.rs b/src/test/ui/dropck/reject-specialized-drops-8142.rs similarity index 100% rename from src/test/ui/reject-specialized-drops-8142.rs rename to src/test/ui/dropck/reject-specialized-drops-8142.rs diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/dropck/reject-specialized-drops-8142.stderr similarity index 100% rename from src/test/ui/reject-specialized-drops-8142.stderr rename to src/test/ui/dropck/reject-specialized-drops-8142.stderr From 21f754de2ac507c8ebc50d857264c224c1c76120 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 12 Nov 2020 15:39:21 +0100 Subject: [PATCH 07/11] check `Drop` specialization of const params --- .../dropck/reject-specialized-drops-8142.rs | 9 +++ .../reject-specialized-drops-8142.stderr | 80 ++++++++++++------- 2 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/test/ui/dropck/reject-specialized-drops-8142.rs b/src/test/ui/dropck/reject-specialized-drops-8142.rs index c4671736d79ec..02e8665cd2e3b 100644 --- a/src/test/ui/dropck/reject-specialized-drops-8142.rs +++ b/src/test/ui/dropck/reject-specialized-drops-8142.rs @@ -1,5 +1,6 @@ // Issue 8142: Test that Drop impls cannot be specialized beyond the // predicates attached to the type definition itself. +#![feature(min_const_generics)] trait Bound { fn foo(&self) { } } struct K<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } @@ -15,6 +16,8 @@ struct T<'t,Ts:'t> { x: &'t Ts } struct U; struct V { x: *const Tva, y: *const Tvb } struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } +struct X; +struct Y; enum Enum { Variant(T) } struct TupleStruct(T); @@ -58,6 +61,12 @@ impl Drop for V { fn drop(&mut self) { } } // REJECT impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter `'lw` +impl Drop for X<3> { fn drop(&mut self) { } } // REJECT +//~^ ERROR `Drop` impls cannot be specialized + +impl Drop for Y { fn drop(&mut self) { } } // REJECT +//~^ ERROR `Drop` impls cannot be specialized + impl Drop for Enum { fn drop(&mut self) { } } // REJECT //~^ ERROR `Drop` impl requires `AddsBnd: Bound` diff --git a/src/test/ui/dropck/reject-specialized-drops-8142.stderr b/src/test/ui/dropck/reject-specialized-drops-8142.stderr index eac2461753355..284cf59c822bd 100644 --- a/src/test/ui/dropck/reject-specialized-drops-8142.stderr +++ b/src/test/ui/dropck/reject-specialized-drops-8142.stderr @@ -1,151 +1,175 @@ error[E0367]: `Drop` impl requires `'adds_bnd: 'al` but the struct it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:23:20 + --> $DIR/reject-specialized-drops-8142.rs:26:20 | LL | impl<'al,'adds_bnd:'al> Drop for K<'al,'adds_bnd> { // REJECT | ^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:5:1 + --> $DIR/reject-specialized-drops-8142.rs:6:1 | LL | struct K<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0367]: `Drop` impl requires `'adds_bnd: 'al` but the struct it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:27:67 + --> $DIR/reject-specialized-drops-8142.rs:30:67 | LL | impl<'al,'adds_bnd> Drop for L<'al,'adds_bnd> where 'adds_bnd:'al { // REJECT | ^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:6:1 + --> $DIR/reject-specialized-drops-8142.rs:7:1 | LL | struct L<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/reject-specialized-drops-8142.rs:33:1 + --> $DIR/reject-specialized-drops-8142.rs:36:1 | LL | impl Drop for N<'static> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | = note: expected struct `N<'n>` found struct `N<'static>` -note: the lifetime `'n` as defined on the struct at 8:10... - --> $DIR/reject-specialized-drops-8142.rs:8:10 +note: the lifetime `'n` as defined on the struct at 9:10... + --> $DIR/reject-specialized-drops-8142.rs:9:10 | LL | struct N<'n> { x: &'n i8 } | ^^ = note: ...does not necessarily outlive the static lifetime error[E0366]: `Drop` impls cannot be specialized - --> $DIR/reject-specialized-drops-8142.rs:40:1 + --> $DIR/reject-specialized-drops-8142.rs:43:1 | LL | impl Drop for P { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: use the same sequence of generic type, lifetime and const parameters as the struct definition - --> $DIR/reject-specialized-drops-8142.rs:10:1 + --> $DIR/reject-specialized-drops-8142.rs:11:1 | LL | struct P { x: *const Tp } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the struct it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:43:14 + --> $DIR/reject-specialized-drops-8142.rs:46:14 | LL | impl Drop for Q { fn drop(&mut self) { } } // REJECT | ^^^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:11:1 + --> $DIR/reject-specialized-drops-8142.rs:12:1 | LL | struct Q { x: *const Tq } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0367]: `Drop` impl requires `AddsRBnd: 'rbnd` but the struct it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:46:21 + --> $DIR/reject-specialized-drops-8142.rs:49:21 | LL | impl<'rbnd,AddsRBnd:'rbnd> Drop for R { fn drop(&mut self) { } } // REJECT | ^^^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:12:1 + --> $DIR/reject-specialized-drops-8142.rs:13:1 | LL | struct R { x: *const Tr } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0366]: `Drop` impls cannot be specialized - --> $DIR/reject-specialized-drops-8142.rs:55:1 + --> $DIR/reject-specialized-drops-8142.rs:58:1 | LL | impl Drop for V { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: use the same sequence of generic type, lifetime and const parameters as the struct definition - --> $DIR/reject-specialized-drops-8142.rs:16:1 + --> $DIR/reject-specialized-drops-8142.rs:17:1 | LL | struct V { x: *const Tva, y: *const Tvb } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'lw` due to conflicting requirements - --> $DIR/reject-specialized-drops-8142.rs:58:1 + --> $DIR/reject-specialized-drops-8142.rs:61:1 | LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime `'l1` as defined on the struct at 17:10... - --> $DIR/reject-specialized-drops-8142.rs:17:10 +note: first, the lifetime cannot outlive the lifetime `'l1` as defined on the struct at 18:10... + --> $DIR/reject-specialized-drops-8142.rs:18:10 | LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^ -note: ...but the lifetime must also be valid for the lifetime `'l2` as defined on the struct at 17:15... - --> $DIR/reject-specialized-drops-8142.rs:17:15 +note: ...but the lifetime must also be valid for the lifetime `'l2` as defined on the struct at 18:15... + --> $DIR/reject-specialized-drops-8142.rs:18:15 | LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^ note: ...so that the types are compatible - --> $DIR/reject-specialized-drops-8142.rs:58:1 + --> $DIR/reject-specialized-drops-8142.rs:61:1 | LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected `W<'l1, 'l2>` found `W<'_, '_>` +error[E0366]: `Drop` impls cannot be specialized + --> $DIR/reject-specialized-drops-8142.rs:64:1 + | +LL | impl Drop for X<3> { fn drop(&mut self) { } } // REJECT + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: use the same sequence of generic type, lifetime and const parameters as the struct definition + --> $DIR/reject-specialized-drops-8142.rs:19:1 + | +LL | struct X; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0366]: `Drop` impls cannot be specialized + --> $DIR/reject-specialized-drops-8142.rs:67:1 + | +LL | impl Drop for Y { fn drop(&mut self) { } } // REJECT + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: use the same sequence of generic type, lifetime and const parameters as the struct definition + --> $DIR/reject-specialized-drops-8142.rs:20:1 + | +LL | struct Y; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the enum it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:61:14 + --> $DIR/reject-specialized-drops-8142.rs:70:14 | LL | impl Drop for Enum { fn drop(&mut self) { } } // REJECT | ^^^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:19:1 + --> $DIR/reject-specialized-drops-8142.rs:22:1 | LL | enum Enum { Variant(T) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the struct it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:64:14 + --> $DIR/reject-specialized-drops-8142.rs:73:14 | LL | impl Drop for TupleStruct { fn drop(&mut self) { } } // REJECT | ^^^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:20:1 + --> $DIR/reject-specialized-drops-8142.rs:23:1 | LL | struct TupleStruct(T); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the union it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:67:21 + --> $DIR/reject-specialized-drops-8142.rs:76:21 | LL | impl Drop for Union { fn drop(&mut self) { } } // REJECT | ^^^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:21:1 + --> $DIR/reject-specialized-drops-8142.rs:24:1 | LL | union Union { f: T } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 13 previous errors Some errors have detailed explanations: E0308, E0366, E0367, E0495. For more information about an error, try `rustc --explain E0308`. From e24a4b4690f73dc834c2f3d5c7b454c1943d0e3a Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 28 Oct 2020 01:11:03 +0000 Subject: [PATCH 08/11] Add type to `ConstKind::Placeholder` --- .../src/infer/canonical/canonicalizer.rs | 10 ++++----- .../rustc_infer/src/infer/canonical/mod.rs | 6 ++--- .../src/infer/higher_ranked/mod.rs | 2 +- compiler/rustc_middle/src/infer/canonical.rs | 22 ++++++++++--------- compiler/rustc_middle/src/ty/codec.rs | 2 +- compiler/rustc_middle/src/ty/consts/kind.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 11 ++++++---- compiler/rustc_middle/src/ty/mod.rs | 17 +++++++++----- 8 files changed, 41 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 871fc4fafe269..f554b51800a72 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -277,7 +277,7 @@ impl CanonicalizeRegionMode for CanonicalizeFreeRegionsOtherThanStatic { struct Canonicalizer<'cx, 'tcx> { infcx: Option<&'cx InferCtxt<'cx, 'tcx>>, tcx: TyCtxt<'tcx>, - variables: SmallVec<[CanonicalVarInfo; 8]>, + variables: SmallVec<[CanonicalVarInfo<'tcx>; 8]>, query_state: &'cx mut OriginalQueryValues<'tcx>, // Note that indices is only used once `var_values` is big enough to be // heap-allocated. @@ -542,7 +542,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// or returns an existing variable if `kind` has already been /// seen. `kind` is expected to be an unbound variable (or /// potentially a free region). - fn canonical_var(&mut self, info: CanonicalVarInfo, kind: GenericArg<'tcx>) -> BoundVar { + fn canonical_var(&mut self, info: CanonicalVarInfo<'tcx>, kind: GenericArg<'tcx>) -> BoundVar { let Canonicalizer { variables, query_state, indices, .. } = self; let var_values = &mut query_state.var_values; @@ -621,7 +621,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// representing the region `r`; return a region referencing it. fn canonical_var_for_region( &mut self, - info: CanonicalVarInfo, + info: CanonicalVarInfo<'tcx>, r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { let var = self.canonical_var(info, r.into()); @@ -633,7 +633,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// if `ty_var` is bound to anything; if so, canonicalize /// *that*. Otherwise, create a new canonical variable for /// `ty_var`. - fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo, ty_var: Ty<'tcx>) -> Ty<'tcx> { + fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo<'tcx>, ty_var: Ty<'tcx>) -> Ty<'tcx> { let infcx = self.infcx.expect("encountered ty-var without infcx"); let bound_to = infcx.shallow_resolve(ty_var); if bound_to != ty_var { @@ -650,7 +650,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// `const_var`. fn canonicalize_const_var( &mut self, - info: CanonicalVarInfo, + info: CanonicalVarInfo<'tcx>, const_var: &'tcx ty::Const<'tcx>, ) -> &'tcx ty::Const<'tcx> { let infcx = self.infcx.expect("encountered const-var without infcx"); diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 2b8c46f1de42d..0c26639e9b0fe 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -82,7 +82,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { fn instantiate_canonical_vars( &self, span: Span, - variables: &List, + variables: &List>, universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, ) -> CanonicalVarValues<'tcx> { let var_values: IndexVec> = variables @@ -100,7 +100,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { fn instantiate_canonical_var( &self, span: Span, - cv_info: CanonicalVarInfo, + cv_info: CanonicalVarInfo<'tcx>, universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, ) -> GenericArg<'tcx> { match cv_info.kind { @@ -154,7 +154,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { self.tcx .mk_const(ty::Const { val: ty::ConstKind::Placeholder(placeholder_mapped), - ty: self.tcx.ty_error(), // FIXME(const_generics) + ty: name.ty, }) .into() } diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index e3365e8590b5e..4a5fd4b2aa5c8 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(ty::PlaceholderConst { universe: next_universe, - name: bound_var, + name: ty::BoundConst { var: bound_var, ty }, }), ty, }) diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 1e15ae49a0c38..947b016a1fc93 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -40,7 +40,7 @@ pub struct Canonical<'tcx, V> { pub value: V, } -pub type CanonicalVarInfos<'tcx> = &'tcx List; +pub type CanonicalVarInfos<'tcx> = &'tcx List>; /// A set of values corresponding to the canonical variables from some /// `Canonical`. You can give these values to @@ -88,11 +88,11 @@ impl Default for OriginalQueryValues<'tcx> { /// a copy of the canonical value in some other inference context, /// with fresh inference variables replacing the canonical values. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] -pub struct CanonicalVarInfo { - pub kind: CanonicalVarKind, +pub struct CanonicalVarInfo<'tcx> { + pub kind: CanonicalVarKind<'tcx>, } -impl CanonicalVarInfo { +impl<'tcx> CanonicalVarInfo<'tcx> { pub fn universe(&self) -> ty::UniverseIndex { self.kind.universe() } @@ -113,7 +113,7 @@ impl CanonicalVarInfo { /// in the type-theory sense of the term -- i.e., a "meta" type system /// that analyzes type-like values. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] -pub enum CanonicalVarKind { +pub enum CanonicalVarKind<'tcx> { /// Some kind of type inference variable. Ty(CanonicalTyVarKind), @@ -132,10 +132,10 @@ pub enum CanonicalVarKind { Const(ty::UniverseIndex), /// A "placeholder" that represents "any const". - PlaceholderConst(ty::PlaceholderConst), + PlaceholderConst(ty::PlaceholderConst<'tcx>), } -impl CanonicalVarKind { +impl<'tcx> CanonicalVarKind<'tcx> { pub fn universe(self) -> ty::UniverseIndex { match self { CanonicalVarKind::Ty(kind) => match kind { @@ -287,9 +287,11 @@ pub type QueryOutlivesConstraint<'tcx> = ty::Binder, Region<'tcx>>>; CloneTypeFoldableAndLiftImpls! { - crate::infer::canonical::Certainty, - crate::infer::canonical::CanonicalVarInfo, - crate::infer::canonical::CanonicalVarKind, + for <'tcx> { + crate::infer::canonical::Certainty, + crate::infer::canonical::CanonicalVarInfo<'tcx>, + crate::infer::canonical::CanonicalVarKind<'tcx>, + } } CloneTypeFoldableImpls! { diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index aaf6a8570437c..1def4936860f1 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -278,7 +278,7 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::Region<'tcx> { impl<'tcx, D: TyDecoder<'tcx>> Decodable for CanonicalVarInfos<'tcx> { fn decode(decoder: &mut D) -> Result { let len = decoder.read_usize()?; - let interned: Result, _> = + let interned: Result>, _> = (0..len).map(|_| Decodable::decode(decoder)).collect(); Ok(decoder.tcx().intern_canonical_var_infos(interned?.as_slice())) } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index ede28522000af..ca51f2a941174 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -23,7 +23,7 @@ pub enum ConstKind<'tcx> { Bound(ty::DebruijnIndex, ty::BoundVar), /// A placeholder const - universally quantified higher-ranked const. - Placeholder(ty::PlaceholderConst), + Placeholder(ty::PlaceholderConst<'tcx>), /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f6ea6743a0e04..4b7d6148fd39a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -83,7 +83,7 @@ pub struct CtxtInterners<'tcx> { type_: InternedSet<'tcx, TyS<'tcx>>, type_list: InternedSet<'tcx, List>>, substs: InternedSet<'tcx, InternalSubsts<'tcx>>, - canonical_var_infos: InternedSet<'tcx, List>, + canonical_var_infos: InternedSet<'tcx, List>>, region: InternedSet<'tcx, RegionKind>, existential_predicates: InternedSet<'tcx, List>>, predicate: InternedSet<'tcx, PredicateInner<'tcx>>, @@ -1613,7 +1613,7 @@ nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>} nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>} nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>} nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} -nop_list_lift! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo} +nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>} nop_list_lift! {projs; ProjectionKind => ProjectionKind} // This is the impl for `&'a InternalSubsts<'a>`. @@ -2049,7 +2049,7 @@ macro_rules! slice_interners { slice_interners!( type_list: _intern_type_list(Ty<'tcx>), substs: _intern_substs(GenericArg<'tcx>), - canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo), + canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>), existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>), predicates: _intern_predicates(Predicate<'tcx>), projs: _intern_projs(ProjectionKind), @@ -2448,7 +2448,10 @@ impl<'tcx> TyCtxt<'tcx> { if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) } } - pub fn intern_canonical_var_infos(self, ts: &[CanonicalVarInfo]) -> CanonicalVarInfos<'tcx> { + pub fn intern_canonical_var_infos( + self, + ts: &[CanonicalVarInfo<'tcx>], + ) -> CanonicalVarInfos<'tcx> { if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 845fa8a47ae2c..1f0164562ec84 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1576,11 +1576,9 @@ impl UniverseIndex { } } -/// The "placeholder index" fully defines a placeholder region. -/// Placeholder regions are identified by both a **universe** as well -/// as a "bound-region" within that universe. The `bound_region` is -/// basically a name -- distinct bound regions within the same -/// universe are just two regions with an unknown relationship to one +/// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are +/// identified by both a universe, as well as a name residing within that universe. Distinct bound +/// regions/types/consts within the same universe simply have an unknown relationship to one /// another. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)] pub struct Placeholder { @@ -1602,7 +1600,14 @@ pub type PlaceholderRegion = Placeholder; pub type PlaceholderType = Placeholder; -pub type PlaceholderConst = Placeholder; +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] +#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)] +pub struct BoundConst<'tcx> { + pub var: BoundVar, + pub ty: Ty<'tcx>, +} + +pub type PlaceholderConst<'tcx> = Placeholder>; /// A `DefId` which is potentially bundled with its corresponding generic parameter /// in case `did` is a const argument. From c56add0dcbf49f785b7d823070bc866adc883eb6 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 12 Nov 2020 19:20:47 +0100 Subject: [PATCH 09/11] cg: add explicit test for const param promotion --- src/test/ui/const-generics/promotion.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/test/ui/const-generics/promotion.rs diff --git a/src/test/ui/const-generics/promotion.rs b/src/test/ui/const-generics/promotion.rs new file mode 100644 index 0000000000000..ac568bb75f002 --- /dev/null +++ b/src/test/ui/const-generics/promotion.rs @@ -0,0 +1,11 @@ +// run-pass +// tests that promoting expressions containing const parameters is allowed. +#![feature(min_const_generics)] + +fn promotion_test() -> &'static usize { + &(3 + N) +} + +fn main() { + assert_eq!(promotion_test::<13>(), &16); +} From a06fd1f4f4b71b0571f2c1f35e981a1863638765 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 12 Nov 2020 21:55:26 +0100 Subject: [PATCH 10/11] Ensure that INVALID_CODEBLOCK_ATTRIBUTES lint is emitted --- src/test/rustdoc-ui/check-fail.rs | 15 ++++++- src/test/rustdoc-ui/check-fail.stderr | 60 +++++++++++++++------------ 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/src/test/rustdoc-ui/check-fail.rs b/src/test/rustdoc-ui/check-fail.rs index ccc9d24c1595a..291fc112c3407 100644 --- a/src/test/rustdoc-ui/check-fail.rs +++ b/src/test/rustdoc-ui/check-fail.rs @@ -1,10 +1,21 @@ // compile-flags: -Z unstable-options --check #![deny(missing_docs)] -//~^ ERROR -//~^^ ERROR #![deny(rustdoc)] +//! ```rust,testharness +//~^ ERROR +//! let x = 12; +//! ``` + pub fn foo() {} //~^ ERROR //~^^ ERROR + +/// hello +//~^ ERROR +/// +/// ```rust,testharness +/// let x = 12; +/// ``` +pub fn bar() {} diff --git a/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr index 979b2292f609b..b4f255642da53 100644 --- a/src/test/rustdoc-ui/check-fail.stderr +++ b/src/test/rustdoc-ui/check-fail.stderr @@ -1,13 +1,8 @@ -error: missing documentation for the crate - --> $DIR/check-fail.rs:3:1 +error: missing documentation for a function + --> $DIR/check-fail.rs:11:1 | -LL | / #![deny(missing_docs)] -LL | | -LL | | -LL | | #![deny(rustdoc)] -LL | | -LL | | pub fn foo() {} - | |_______________^ +LL | pub fn foo() {} + | ^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/check-fail.rs:3:9 @@ -15,35 +10,48 @@ note: the lint level is defined here LL | #![deny(missing_docs)] | ^^^^^^^^^^^^ -error: missing documentation for a function - --> $DIR/check-fail.rs:8:1 +error: missing code example in this documentation + --> $DIR/check-fail.rs:11:1 | LL | pub fn foo() {} - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/check-fail.rs:4:9 + | +LL | #![deny(rustdoc)] + | ^^^^^^^ + = note: `#[deny(missing_doc_code_examples)]` implied by `#[deny(rustdoc)]` -error: missing code example in this documentation - --> $DIR/check-fail.rs:3:1 +error: unknown attribute `testharness`. Did you mean `test_harness`? + --> $DIR/check-fail.rs:6:1 | -LL | / #![deny(missing_docs)] -LL | | -LL | | -LL | | #![deny(rustdoc)] +LL | / //! ```rust,testharness LL | | -LL | | pub fn foo() {} - | |_______________^ +LL | | //! let x = 12; +LL | | //! ``` + | |_______^ | note: the lint level is defined here - --> $DIR/check-fail.rs:6:9 + --> $DIR/check-fail.rs:4:9 | LL | #![deny(rustdoc)] | ^^^^^^^ - = note: `#[deny(missing_doc_code_examples)]` implied by `#[deny(rustdoc)]` + = note: `#[deny(invalid_codeblock_attributes)]` implied by `#[deny(rustdoc)]` + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function -error: missing code example in this documentation - --> $DIR/check-fail.rs:8:1 +error: unknown attribute `testharness`. Did you mean `test_harness`? + --> $DIR/check-fail.rs:15:1 | -LL | pub fn foo() {} - | ^^^^^^^^^^^^^^^ +LL | / /// hello +LL | | +LL | | /// +LL | | /// ```rust,testharness +LL | | /// let x = 12; +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function error: aborting due to 4 previous errors From 4e5848349ce6f8b79dc9b2eba57e833431761bc7 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Thu, 12 Nov 2020 20:14:57 -0800 Subject: [PATCH 11/11] Update library/std/src/collections/hash/map.rs Co-authored-by: Mara Bos --- library/std/src/collections/hash/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 03d8b11a51aef..c6a68a4467193 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -34,7 +34,7 @@ use crate::sys; /// attacks such as HashDoS. /// /// The hashing algorithm can be replaced on a per-`HashMap` basis using the -/// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. +/// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. /// There are many alternative [hashing algorithms available on crates.io]. /// /// It is required that the keys implement the [`Eq`] and [`Hash`] traits, although