From 9aef9a2324fc1a1951e470c645df6c1b11a5ffdc Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Sun, 21 Nov 2021 00:24:38 -0800 Subject: [PATCH 1/8] Inhibit clicks on summary's children A byproduct of using `
` and `` to show/hide detailed documentation was that clicking any part of a method heading (or impl heading) would show or hide the documentation. This was not super noticeable because clicking a link inside the method heading would navigate to that link. But clicking any unlinked black text in a method heading would trigger the behavior. That behavior was somewhat unexpected, and means that if you try to click a type name in a method heading, but miss by a few pixels, you get a confusing surprise. This change inhibits that behavior by putting an event listener on most summaries that cancels the event unless the event target was the summary itself. In practice, that means it cancels the event unless the target was the "[+]" / "[-]", because the rest of the heading is wrapped inside a `
`, which is the target for anything that doesn't have a more specific target. --- src/librustdoc/html/static/js/main.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 4b55a0a69b663..908d3f65fd35b 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -886,6 +886,14 @@ function hideThemeButtonState() { } }); + onEachLazy(document.querySelectorAll(".rustdoc-toggle > summary:not(.hideme)"), function(el) { + el.addEventListener("click", function(e) { + if (e.target.tagName != "SUMMARY") { + e.preventDefault(); + } + }) + }); + onEachLazy(document.getElementsByClassName("notable-traits"), function(e) { e.onclick = function() { this.getElementsByClassName('notable-traits-tooltiptext')[0] From 7f35556a256241579f6f1b0905fd671bc1182af1 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Mon, 22 Nov 2021 00:49:57 -0800 Subject: [PATCH 2/8] Add GUI test for clicking on non-toggle summary --- src/librustdoc/html/static/js/main.js | 2 +- src/test/rustdoc-gui/src/lib2/lib.rs | 2 ++ src/test/rustdoc-gui/toggle-click-deadspace.goml | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/test/rustdoc-gui/toggle-click-deadspace.goml diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 908d3f65fd35b..32aa82195a962 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -891,7 +891,7 @@ function hideThemeButtonState() { if (e.target.tagName != "SUMMARY") { e.preventDefault(); } - }) + }); }); onEachLazy(document.getElementsByClassName("notable-traits"), function(e) { diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs index f2e76b546c4af..79354ec874507 100644 --- a/src/test/rustdoc-gui/src/lib2/lib.rs +++ b/src/test/rustdoc-gui/src/lib2/lib.rs @@ -22,6 +22,8 @@ pub struct Foo { } impl Foo { + /// Some documentation + /// # A Heading pub fn a_method(&self) {} } diff --git a/src/test/rustdoc-gui/toggle-click-deadspace.goml b/src/test/rustdoc-gui/toggle-click-deadspace.goml new file mode 100644 index 0000000000000..4d08927a7bede --- /dev/null +++ b/src/test/rustdoc-gui/toggle-click-deadspace.goml @@ -0,0 +1,8 @@ +// This test ensures that clicking on a method summary, but not on the "[-]", +// doesn't toggle the
. +goto: file://|DOC_PATH|/test_docs/struct.Foo.html +assert-attribute: (".impl-items .rustdoc-toggle", {"open": ""}) +click: "h4.code-header" // This is the position of "pub" in "pub fn a_method" +assert-attribute: (".impl-items .rustdoc-toggle", {"open": ""}) +click: ".impl-items .rustdoc-toggle summary::before" // This is the position of "[-]" next to that pub fn. +assert-attribute-false: (".impl-items .rustdoc-toggle", {"open": ""}) From bb7ec7b7e94cfb719283b051d462daa2f707c077 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 22 Nov 2021 11:55:00 -0600 Subject: [PATCH 3/8] Give people a single link they can click in the contributing guide Doc Jones mentioned that one of the things making it hard to get started is that the amount of information is overwhelming, between the dev-guide, contributing guide, and discussion platforms. This gives people a single link they can click to ask for help. --- CONTRIBUTING.md | 11 ++++++----- README.md | 5 ++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2827a46ae6f73..223fd0065bf4a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,13 +3,14 @@ Thank you for your interest in contributing to Rust! There are many ways to contribute and we appreciate all of them. +The best way to get started is by asking for help in the [#new +members](https://rust-lang.zulipchat.com/#narrow/stream/122652-new-members) +Zulip stream. We have lots of docs below of how to get started on your own, but +the Zulip stream is the best place to *ask* for help. + Documentation for contributing to Rust is located in the [Guide to Rustc Development](https://rustc-dev-guide.rust-lang.org/), commonly known as the [rustc-dev-guide]. Despite the name, this guide documents -not just how to develop rustc (the Rust compiler), but also how to contribute to any part -of the Rust project. - -To get started with contributing, please read the [Contributing to Rust] chapter of the guide. -That chapter explains how to get your development environment set up and how to get help. +not just how to develop rustc (the Rust compiler), but also how to contribute to the standard library and rustdoc. ## About the [rustc-dev-guide] diff --git a/README.md b/README.md index 32fab9fc25de5..78edac9d12c13 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,10 @@ standard library, and documentation. **Note: this README is for _users_ rather than _contributors_. If you wish to _contribute_ to the compiler, you should read the -[Getting Started][gettingstarted] section of the rustc-dev-guide instead.** +[Getting Started][gettingstarted] section of the rustc-dev-guide instead. +You can ask for help in the [#new members Zulip stream][new-members].** + +[new-members]: https://rust-lang.zulipchat.com/#narrow/stream/122652-new-members ## Quick Start From 6d61d87b227f2314e06f8da7c33bab9633119006 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Mon, 22 Nov 2021 16:25:28 +0000 Subject: [PATCH 4/8] Split inline const to two feature gates --- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_feature/src/active.rs | 2 ++ compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/mod.rs | 8 +++++-- compiler/rustc_parse/src/parser/pat.rs | 4 ++-- compiler/rustc_span/src/symbol.rs | 1 + .../src/language-features/inline-const-pat.md | 24 +++++++++++++++++++ .../src/language-features/inline-const.md | 17 ++----------- .../feature-gate-inline_const_pat.rs | 4 ++++ .../feature-gate-inline_const_pat.stderr | 12 ++++++++++ .../range_pat_interactions0.rs | 2 +- .../range_pat_interactions3.rs | 2 +- .../range_pat_interactions3.stderr | 4 ++-- .../inline-const/const-match-pat-generic.rs | 2 +- .../inline-const/const-match-pat-inference.rs | 2 +- .../const-match-pat-lifetime-err.rs | 2 +- .../inline-const/const-match-pat-lifetime.rs | 1 + .../ui/inline-const/const-match-pat-range.rs | 2 +- src/test/ui/inline-const/const-match-pat.rs | 2 +- .../ui/lint/dead-code/anon-const-in-pat.rs | 2 +- .../ui/pattern/non-structural-match-types.rs | 2 +- 21 files changed, 67 insertions(+), 31 deletions(-) create mode 100644 src/doc/unstable-book/src/language-features/inline-const-pat.md create mode 100644 src/test/ui/feature-gates/feature-gate-inline_const_pat.rs create mode 100644 src/test/ui/feature-gates/feature-gate-inline_const_pat.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index b011a2e8117af..6a19984f8ea46 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -719,6 +719,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { gate_all!(const_trait_impl, "const trait impls are experimental"); gate_all!(half_open_range_patterns, "half-open range patterns are unstable"); gate_all!(inline_const, "inline-const is experimental"); + gate_all!(inline_const_pat, "inline-const in pattern position is experimental"); gate_all!( const_generics_defaults, "default values for const generic parameters are experimental" diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 608581306bef5..34a8de67ca0f5 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -410,6 +410,8 @@ declare_features! ( (incomplete, inherent_associated_types, "1.52.0", Some(8995), None), /// Allow anonymous constants from an inline `const` block (incomplete, inline_const, "1.49.0", Some(76001), None), + /// Allow anonymous constants from an inline `const` block in pattern position + (incomplete, inline_const_pat, "1.58.0", Some(76001), None), /// Allows using `pointer` and `reference` in intra-doc links (active, intra_doc_pointers, "1.51.0", Some(80896), None), /// Allows `#[instruction_set(_)]` attribute diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0c8c45410bd0e..3669a4fce9cbf 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1243,7 +1243,7 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(kw::Unsafe) { self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs) } else if self.check_inline_const(0) { - self.parse_const_block(lo.to(self.token.span)) + self.parse_const_block(lo.to(self.token.span), false) } else if self.is_do_catch_block() { self.recover_do_catch(attrs) } else if self.is_try_block() { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index e50b983ec6216..9212aaa87d194 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1095,8 +1095,12 @@ impl<'a> Parser<'a> { } /// Parses inline const expressions. - fn parse_const_block(&mut self, span: Span) -> PResult<'a, P> { - self.sess.gated_spans.gate(sym::inline_const, span); + fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P> { + if pat { + self.sess.gated_spans.gate(sym::inline_const_pat, span); + } else { + self.sess.gated_spans.gate(sym::inline_const, span); + } self.eat_keyword(kw::Const); let blk = self.parse_block()?; let anon_const = AnonConst { diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 3b5a297103c0a..bb3947bb47a25 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -437,7 +437,7 @@ impl<'a> Parser<'a> { PatKind::Box(pat) } else if self.check_inline_const(0) { // Parse `const pat` - let const_expr = self.parse_const_block(lo.to(self.token.span))?; + let const_expr = self.parse_const_block(lo.to(self.token.span), true)?; if let Some(re) = self.parse_range_end() { self.parse_pat_range_begin_with(const_expr, re)? @@ -884,7 +884,7 @@ impl<'a> Parser<'a> { fn parse_pat_range_end(&mut self) -> PResult<'a, P> { if self.check_inline_const(0) { - self.parse_const_block(self.token.span) + self.parse_const_block(self.token.span, true) } else if self.check_path() { let lo = self.token.span; let (qself, path) = if self.eat_lt() { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 0d556b5eda609..46f1ce0797f62 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -731,6 +731,7 @@ symbols! { inlateout, inline, inline_const, + inline_const_pat, inout, instruction_set, intel, diff --git a/src/doc/unstable-book/src/language-features/inline-const-pat.md b/src/doc/unstable-book/src/language-features/inline-const-pat.md new file mode 100644 index 0000000000000..5f0f7547a0a89 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/inline-const-pat.md @@ -0,0 +1,24 @@ +# `inline_const_pat` + +The tracking issue for this feature is: [#76001] + +See also [`inline_const`](inline-const.md) + +------ + +This feature allows you to use inline constant expressions in pattern position: + +```rust +#![feature(inline_const_pat)] + +const fn one() -> i32 { 1 } + +let some_int = 3; +match some_int { + const { 1 + 2 } => println!("Matched 1 + 2"), + const { one() } => println!("Matched const fn returning 1"), + _ => println!("Didn't match anything :("), +} +``` + +[#76001]: https://github.com/rust-lang/rust/issues/76001 diff --git a/src/doc/unstable-book/src/language-features/inline-const.md b/src/doc/unstable-book/src/language-features/inline-const.md index 00e1c79ca3ff3..7be70eed6cedc 100644 --- a/src/doc/unstable-book/src/language-features/inline-const.md +++ b/src/doc/unstable-book/src/language-features/inline-const.md @@ -2,6 +2,8 @@ The tracking issue for this feature is: [#76001] +See also [`inline_const_pat`](inline-const-pat.md) + ------ This feature allows you to use inline constant expressions. For example, you can @@ -27,19 +29,4 @@ fn main() { } ``` -You can also use inline constant expressions in patterns: - -```rust -#![feature(inline_const)] - -const fn one() -> i32 { 1 } - -let some_int = 3; -match some_int { - const { 1 + 2 } => println!("Matched 1 + 2"), - const { one() } => println!("Matched const fn returning 1"), - _ => println!("Didn't match anything :("), -} -``` - [#76001]: https://github.com/rust-lang/rust/issues/76001 diff --git a/src/test/ui/feature-gates/feature-gate-inline_const_pat.rs b/src/test/ui/feature-gates/feature-gate-inline_const_pat.rs new file mode 100644 index 0000000000000..3d0df289fb74a --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-inline_const_pat.rs @@ -0,0 +1,4 @@ +fn main() { + let const { () } = (); + //~^ ERROR inline-const in pattern position is experimental [E0658] +} diff --git a/src/test/ui/feature-gates/feature-gate-inline_const_pat.stderr b/src/test/ui/feature-gates/feature-gate-inline_const_pat.stderr new file mode 100644 index 0000000000000..ca533d8505cf7 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-inline_const_pat.stderr @@ -0,0 +1,12 @@ +error[E0658]: inline-const in pattern position is experimental + --> $DIR/feature-gate-inline_const_pat.rs:2:9 + | +LL | let const { () } = (); + | ^^^^^ + | + = note: see issue #76001 for more information + = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/half-open-range-patterns/range_pat_interactions0.rs b/src/test/ui/half-open-range-patterns/range_pat_interactions0.rs index 4f478a6988142..8f745e8104f81 100644 --- a/src/test/ui/half-open-range-patterns/range_pat_interactions0.rs +++ b/src/test/ui/half-open-range-patterns/range_pat_interactions0.rs @@ -2,7 +2,7 @@ #![allow(incomplete_features)] #![feature(exclusive_range_pattern)] #![feature(half_open_range_patterns)] -#![feature(inline_const)] +#![feature(inline_const_pat)] fn main() { let mut if_lettable = vec![]; diff --git a/src/test/ui/half-open-range-patterns/range_pat_interactions3.rs b/src/test/ui/half-open-range-patterns/range_pat_interactions3.rs index 0afb512605912..41c7e46dfc1ed 100644 --- a/src/test/ui/half-open-range-patterns/range_pat_interactions3.rs +++ b/src/test/ui/half-open-range-patterns/range_pat_interactions3.rs @@ -12,7 +12,7 @@ fn main() { y @ (0..5 | 6) => or_two.push(y), //~^ exclusive range pattern syntax is experimental y @ 0..const { 5 + 1 } => assert_eq!(y, 5), - //~^ inline-const is experimental + //~^ inline-const in pattern position is experimental //~| exclusive range pattern syntax is experimental y @ -5.. => range_from.push(y), y @ ..-7 => assert_eq!(y, -8), diff --git a/src/test/ui/half-open-range-patterns/range_pat_interactions3.stderr b/src/test/ui/half-open-range-patterns/range_pat_interactions3.stderr index 8278e7cc6cfde..5e36996a462b2 100644 --- a/src/test/ui/half-open-range-patterns/range_pat_interactions3.stderr +++ b/src/test/ui/half-open-range-patterns/range_pat_interactions3.stderr @@ -7,14 +7,14 @@ LL | y @ ..-7 => assert_eq!(y, -8), = note: see issue #67264 for more information = help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable -error[E0658]: inline-const is experimental +error[E0658]: inline-const in pattern position is experimental --> $DIR/range_pat_interactions3.rs:14:20 | LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5), | ^^^^^ | = note: see issue #76001 for more information - = help: add `#![feature(inline_const)]` to the crate attributes to enable + = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable error[E0658]: exclusive range pattern syntax is experimental --> $DIR/range_pat_interactions3.rs:10:17 diff --git a/src/test/ui/inline-const/const-match-pat-generic.rs b/src/test/ui/inline-const/const-match-pat-generic.rs index 61680d653d021..4486411698af9 100644 --- a/src/test/ui/inline-const/const-match-pat-generic.rs +++ b/src/test/ui/inline-const/const-match-pat-generic.rs @@ -1,5 +1,5 @@ #![allow(incomplete_features)] -#![feature(inline_const)] +#![feature(inline_const_pat)] // rust-lang/rust#82518: ICE with inline-const in match referencing const-generic parameter diff --git a/src/test/ui/inline-const/const-match-pat-inference.rs b/src/test/ui/inline-const/const-match-pat-inference.rs index 61188ed5d47bd..d83ae6e983486 100644 --- a/src/test/ui/inline-const/const-match-pat-inference.rs +++ b/src/test/ui/inline-const/const-match-pat-inference.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(inline_const)] +#![feature(inline_const_pat)] #![allow(incomplete_features)] fn main() { diff --git a/src/test/ui/inline-const/const-match-pat-lifetime-err.rs b/src/test/ui/inline-const/const-match-pat-lifetime-err.rs index bc5aa24894427..436b8037f3093 100644 --- a/src/test/ui/inline-const/const-match-pat-lifetime-err.rs +++ b/src/test/ui/inline-const/const-match-pat-lifetime-err.rs @@ -2,7 +2,7 @@ #![allow(incomplete_features)] #![feature(const_mut_refs)] -#![feature(inline_const)] +#![feature(inline_const_pat)] use std::marker::PhantomData; diff --git a/src/test/ui/inline-const/const-match-pat-lifetime.rs b/src/test/ui/inline-const/const-match-pat-lifetime.rs index 3d986f0d9ee08..6d943bbcc0160 100644 --- a/src/test/ui/inline-const/const-match-pat-lifetime.rs +++ b/src/test/ui/inline-const/const-match-pat-lifetime.rs @@ -3,6 +3,7 @@ #![allow(incomplete_features)] #![feature(const_mut_refs)] #![feature(inline_const)] +#![feature(inline_const_pat)] use std::marker::PhantomData; diff --git a/src/test/ui/inline-const/const-match-pat-range.rs b/src/test/ui/inline-const/const-match-pat-range.rs index eefe43a1a2297..7dc8c11355ab0 100644 --- a/src/test/ui/inline-const/const-match-pat-range.rs +++ b/src/test/ui/inline-const/const-match-pat-range.rs @@ -1,7 +1,7 @@ // build-pass #![allow(incomplete_features)] -#![feature(inline_const, half_open_range_patterns, exclusive_range_pattern)] +#![feature(inline_const_pat, half_open_range_patterns, exclusive_range_pattern)] fn main() { const N: u32 = 10; let x: u32 = 3; diff --git a/src/test/ui/inline-const/const-match-pat.rs b/src/test/ui/inline-const/const-match-pat.rs index c0dc90d971a49..2f55e16b35cd9 100644 --- a/src/test/ui/inline-const/const-match-pat.rs +++ b/src/test/ui/inline-const/const-match-pat.rs @@ -1,7 +1,7 @@ // run-pass #![allow(incomplete_features)] -#![feature(inline_const)] +#![feature(inline_const_pat)] const MMIO_BIT1: u8 = 4; const MMIO_BIT2: u8 = 5; diff --git a/src/test/ui/lint/dead-code/anon-const-in-pat.rs b/src/test/ui/lint/dead-code/anon-const-in-pat.rs index 4c6211a279a58..d3e39c0de69c8 100644 --- a/src/test/ui/lint/dead-code/anon-const-in-pat.rs +++ b/src/test/ui/lint/dead-code/anon-const-in-pat.rs @@ -1,5 +1,5 @@ // check-pass -#![feature(inline_const)] +#![feature(inline_const_pat)] #![allow(incomplete_features)] #![deny(dead_code)] diff --git a/src/test/ui/pattern/non-structural-match-types.rs b/src/test/ui/pattern/non-structural-match-types.rs index 713418fc5b29a..5c33154736650 100644 --- a/src/test/ui/pattern/non-structural-match-types.rs +++ b/src/test/ui/pattern/non-structural-match-types.rs @@ -2,7 +2,7 @@ #![allow(incomplete_features)] #![allow(unreachable_code)] #![feature(const_async_blocks)] -#![feature(inline_const)] +#![feature(inline_const_pat)] fn main() { match loop {} { From 6f38568decbab94e06e1df740b8b7a140be88e54 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Mon, 22 Nov 2021 20:14:25 +0000 Subject: [PATCH 5/8] `#![feature(inline_const)]` is no longer incomplete --- compiler/rustc_feature/src/active.rs | 2 +- src/test/ui/consts/closure-structural-match-issue-90013.rs | 1 - src/test/ui/consts/const-blocks/fn-call-in-const.rs | 2 +- src/test/ui/inline-const/const-expr-array-init.rs | 1 - src/test/ui/inline-const/const-expr-basic.rs | 2 +- src/test/ui/inline-const/const-expr-inference.rs | 1 - src/test/ui/inline-const/const-expr-lifetime-err.rs | 1 - src/test/ui/inline-const/const-expr-lifetime-err.stderr | 2 +- src/test/ui/inline-const/const-expr-lifetime.rs | 1 - src/test/ui/inline-const/const-expr-macro.rs | 2 +- src/test/ui/inline-const/const-expr-reference.rs | 1 - src/test/ui/simd/intrinsic/generic-elements-pass.rs | 1 - 12 files changed, 5 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 34a8de67ca0f5..c34ecc966d0ae 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -409,7 +409,7 @@ declare_features! ( /// Allows associated types in inherent impls. (incomplete, inherent_associated_types, "1.52.0", Some(8995), None), /// Allow anonymous constants from an inline `const` block - (incomplete, inline_const, "1.49.0", Some(76001), None), + (active, inline_const, "1.49.0", Some(76001), None), /// Allow anonymous constants from an inline `const` block in pattern position (incomplete, inline_const_pat, "1.58.0", Some(76001), None), /// Allows using `pointer` and `reference` in intra-doc links diff --git a/src/test/ui/consts/closure-structural-match-issue-90013.rs b/src/test/ui/consts/closure-structural-match-issue-90013.rs index 7853ee41a9009..1952ddb941e51 100644 --- a/src/test/ui/consts/closure-structural-match-issue-90013.rs +++ b/src/test/ui/consts/closure-structural-match-issue-90013.rs @@ -1,6 +1,5 @@ // Regression test for issue 90013. // check-pass -#![allow(incomplete_features)] #![feature(inline_const)] fn main() { diff --git a/src/test/ui/consts/const-blocks/fn-call-in-const.rs b/src/test/ui/consts/const-blocks/fn-call-in-const.rs index 7936af75d84ac..20496f62712c2 100644 --- a/src/test/ui/consts/const-blocks/fn-call-in-const.rs +++ b/src/test/ui/consts/const-blocks/fn-call-in-const.rs @@ -1,7 +1,7 @@ // run-pass #![feature(inline_const)] -#![allow(unused, incomplete_features)] +#![allow(unused)] // Some type that is not copyable. struct Bar; diff --git a/src/test/ui/inline-const/const-expr-array-init.rs b/src/test/ui/inline-const/const-expr-array-init.rs index 8bb5dab1fa00d..8a92cdbc0f981 100644 --- a/src/test/ui/inline-const/const-expr-array-init.rs +++ b/src/test/ui/inline-const/const-expr-array-init.rs @@ -1,6 +1,5 @@ // build-pass -#![allow(incomplete_features)] #![feature(inline_const)] use std::cell::Cell; diff --git a/src/test/ui/inline-const/const-expr-basic.rs b/src/test/ui/inline-const/const-expr-basic.rs index 9254c96a1e7a6..dac46fe25ecfc 100644 --- a/src/test/ui/inline-const/const-expr-basic.rs +++ b/src/test/ui/inline-const/const-expr-basic.rs @@ -1,7 +1,7 @@ // run-pass -#![allow(incomplete_features)] #![feature(inline_const)] + fn foo() -> i32 { const { let x = 5 + 10; diff --git a/src/test/ui/inline-const/const-expr-inference.rs b/src/test/ui/inline-const/const-expr-inference.rs index 6aa2a2f3367fc..0d5892a74d956 100644 --- a/src/test/ui/inline-const/const-expr-inference.rs +++ b/src/test/ui/inline-const/const-expr-inference.rs @@ -1,7 +1,6 @@ // check-pass #![feature(inline_const)] -#![allow(incomplete_features)] pub fn todo() -> T { const { todo!() } diff --git a/src/test/ui/inline-const/const-expr-lifetime-err.rs b/src/test/ui/inline-const/const-expr-lifetime-err.rs index e56cbc94038a0..0a032a7338ad0 100644 --- a/src/test/ui/inline-const/const-expr-lifetime-err.rs +++ b/src/test/ui/inline-const/const-expr-lifetime-err.rs @@ -1,4 +1,3 @@ -#![allow(incomplete_features)] #![feature(const_mut_refs)] #![feature(inline_const)] diff --git a/src/test/ui/inline-const/const-expr-lifetime-err.stderr b/src/test/ui/inline-const/const-expr-lifetime-err.stderr index 30ecd338a856d..a23f7c9a796c5 100644 --- a/src/test/ui/inline-const/const-expr-lifetime-err.stderr +++ b/src/test/ui/inline-const/const-expr-lifetime-err.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/const-expr-lifetime-err.rs:24:30 + --> $DIR/const-expr-lifetime-err.rs:23:30 | LL | fn foo<'a>() { | -- lifetime `'a` defined here diff --git a/src/test/ui/inline-const/const-expr-lifetime.rs b/src/test/ui/inline-const/const-expr-lifetime.rs index f622f2cbddf48..d883deb2845d3 100644 --- a/src/test/ui/inline-const/const-expr-lifetime.rs +++ b/src/test/ui/inline-const/const-expr-lifetime.rs @@ -1,6 +1,5 @@ // run-pass -#![allow(incomplete_features)] #![feature(const_mut_refs)] #![feature(inline_const)] diff --git a/src/test/ui/inline-const/const-expr-macro.rs b/src/test/ui/inline-const/const-expr-macro.rs index 66b58571751ce..041f3e15a29b9 100644 --- a/src/test/ui/inline-const/const-expr-macro.rs +++ b/src/test/ui/inline-const/const-expr-macro.rs @@ -1,7 +1,7 @@ // run-pass -#![allow(incomplete_features)] #![feature(inline_const)] + macro_rules! do_const_block{ ($val:block) => { const $val } } diff --git a/src/test/ui/inline-const/const-expr-reference.rs b/src/test/ui/inline-const/const-expr-reference.rs index 747f14e4bd0aa..a54d879f69d74 100644 --- a/src/test/ui/inline-const/const-expr-reference.rs +++ b/src/test/ui/inline-const/const-expr-reference.rs @@ -1,6 +1,5 @@ // run-pass -#![allow(incomplete_features)] #![feature(inline_const)] const fn bar() -> i32 { diff --git a/src/test/ui/simd/intrinsic/generic-elements-pass.rs b/src/test/ui/simd/intrinsic/generic-elements-pass.rs index 08544bce45db9..3c913c0adfa60 100644 --- a/src/test/ui/simd/intrinsic/generic-elements-pass.rs +++ b/src/test/ui/simd/intrinsic/generic-elements-pass.rs @@ -2,7 +2,6 @@ // ignore-emscripten FIXME(#45351) hits an LLVM assert #![feature(repr_simd, platform_intrinsics)] -#![allow(incomplete_features)] #![feature(inline_const)] #[repr(simd)] From 7b103e7dd2df75e4e8dbb333bc79ffc7e9304f65 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Mon, 22 Nov 2021 20:17:53 -0500 Subject: [PATCH 6/8] Use `derive_default_enum` in the compiler --- compiler/rustc_infer/src/infer/mod.rs | 9 ++------- compiler/rustc_infer/src/lib.rs | 1 + compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/ty/sty.rs | 9 ++------- compiler/rustc_session/src/config.rs | 9 ++------- compiler/rustc_session/src/lib.rs | 1 + compiler/rustc_trait_selection/src/lib.rs | 1 + compiler/rustc_trait_selection/src/traits/mod.rs | 16 ++++++---------- library/core/src/lib.rs | 1 + 9 files changed, 17 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b874947cc6968..2fd01c2d595fa 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -95,9 +95,10 @@ pub(crate) type UnificationTable<'a, 'tcx, T> = ut::UnificationTable< /// This is used so that the region values inferred by HIR region solving are /// not exposed, and so that we can avoid doing work in HIR typeck that MIR /// typeck will also do. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Default)] pub enum RegionckMode { /// The default mode: report region errors, don't erase regions. + #[default] Solve, /// Erase the results of region after solving. Erase { @@ -108,12 +109,6 @@ pub enum RegionckMode { }, } -impl Default for RegionckMode { - fn default() -> Self { - RegionckMode::Solve - } -} - impl RegionckMode { /// Indicates that the MIR borrowck will repeat these region /// checks, so we should ignore errors if NLL is (unconditionally) diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index d0f1ff649d058..e4b407e7c112d 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -15,6 +15,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(bool_to_option)] #![feature(box_patterns)] +#![feature(derive_default_enum)] #![feature(extend_one)] #![feature(iter_zip)] #![feature(let_else)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 0894b80507581..9ce9f65a49066 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -30,6 +30,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(core_intrinsics)] +#![feature(derive_default_enum)] #![feature(discriminant_kind)] #![feature(exhaustive_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c79e25f4781c8..7e054d1e17fcd 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2263,10 +2263,11 @@ impl<'tcx> TyS<'tcx> { /// a miscompilation or unsoundness. /// /// When in doubt, use `VarianceDiagInfo::default()` -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] pub enum VarianceDiagInfo<'tcx> { /// No additional information - this is the default. /// We will not add any additional information to error messages. + #[default] None, /// We switched our variance because a type occurs inside /// the generic argument of a mutable reference or pointer @@ -2301,9 +2302,3 @@ impl<'tcx> VarianceDiagInfo<'tcx> { } } } - -impl<'tcx> Default for VarianceDiagInfo<'tcx> { - fn default() -> Self { - Self::None - } -} diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 3f0a6b0e2f6a0..1394e6f1c1da0 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -335,9 +335,10 @@ impl Default for ErrorOutputType { } /// Parameter to control path trimming. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] pub enum TrimmedDefPaths { /// `try_print_trimmed_def_path` never prints a trimmed path and never calls the expensive query + #[default] Never, /// `try_print_trimmed_def_path` calls the expensive query, the query doesn't call `delay_good_path_bug` Always, @@ -345,12 +346,6 @@ pub enum TrimmedDefPaths { GoodPath, } -impl Default for TrimmedDefPaths { - fn default() -> Self { - Self::Never - } -} - /// Use tree-based collections to cheaply get a deterministic `Hash` implementation. /// *Do not* switch `BTreeMap` out for an unsorted container type! That would break /// dependency tracking for command-line arguments. Also only hash keys, since tracking diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 6c86f86ecd9bb..399b616915ee1 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,4 +1,5 @@ #![feature(crate_visibility_modifier)] +#![feature(derive_default_enum)] #![feature(min_specialization)] #![feature(once_cell)] #![recursion_limit = "256"] diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 1a049e6ec649d..1820e33b19bf4 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -14,6 +14,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(drain_filter)] +#![feature(derive_default_enum)] #![feature(hash_drain_filter)] #![feature(in_band_lifetimes)] #![feature(iter_zip)] diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 91671994c5ace..4bc22d5d73543 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -82,9 +82,14 @@ pub use self::chalk_fulfill::FulfillmentContext as ChalkFulfillmentContext; pub use rustc_infer::traits::*; /// Whether to skip the leak check, as part of a future compatibility warning step. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +/// +/// The "default" for skip-leak-check corresponds to the current +/// behavior (do not skip the leak check) -- not the behavior we are +/// transitioning into. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] pub enum SkipLeakCheck { Yes, + #[default] No, } @@ -94,15 +99,6 @@ impl SkipLeakCheck { } } -/// The "default" for skip-leak-check corresponds to the current -/// behavior (do not skip the leak check) -- not the behavior we are -/// transitioning into. -impl Default for SkipLeakCheck { - fn default() -> Self { - SkipLeakCheck::No - } -} - /// The mode that trait queries run in. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum TraitQueryMode { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 4a64e2e2d102d..2486999ffb5c1 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -163,6 +163,7 @@ #![cfg_attr(bootstrap, feature(const_raw_ptr_deref))] #![feature(const_refs_to_cell)] #![feature(decl_macro)] +#![feature(derive_default_enum)] #![feature(doc_cfg)] #![feature(doc_notable_trait)] #![feature(doc_primitive)] From b490ccc22746375e154352466fb0d0deafb50194 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 23 Nov 2021 08:09:48 +0100 Subject: [PATCH 7/8] kernel_copy: avoid panic on unexpected OS error According to documentation, the listed errnos should only occur if the `copy_file_range` call cannot be made at all, so the assert be correct. However, since in practice file system drivers (incl. FUSE etc.) can return any errno they want, we should not panic here. Fixes #91152 --- library/std/src/sys/unix/kernel_copy.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/kernel_copy.rs b/library/std/src/sys/unix/kernel_copy.rs index a6b43229ba6b7..f3155fbc0620f 100644 --- a/library/std/src/sys/unix/kernel_copy.rs +++ b/library/std/src/sys/unix/kernel_copy.rs @@ -576,7 +576,7 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> return match err.raw_os_error() { // when file offset + max_length > u64::MAX Some(EOVERFLOW) => CopyResult::Fallback(written), - Some(ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF) => { + Some(ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF) if written == 0 => { // Try fallback io::copy if either: // - Kernel version is < 4.5 (ENOSYS¹) // - Files are mounted on different fs (EXDEV) @@ -584,12 +584,14 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> // - copy_file_range file is immutable or syscall is blocked by seccomp¹ (EPERM) // - copy_file_range cannot be used with pipes or device nodes (EINVAL) // - the writer fd was opened with O_APPEND (EBADF²) + // and no bytes were written successfully yet. (All these errnos should + // not be returned if something was already written, but they happen in + // the wild, see #91152.) // // ¹ these cases should be detected by the initial probe but we handle them here // anyway in case syscall interception changes during runtime // ² actually invalid file descriptors would cause this too, but in that case // the fallback code path is expected to encounter the same error again - assert_eq!(written, 0); CopyResult::Fallback(0) } _ => CopyResult::Error(err, written), From 57494f7c75b4cdfa3cd4d586f606b0898cce4ebd Mon Sep 17 00:00:00 2001 From: Ken Matsui <26405363+ken-matsui@users.noreply.github.com> Date: Sat, 13 Nov 2021 16:39:54 +0900 Subject: [PATCH 8/8] Suggestion to wrap inner types using `allocator_api` in tuple --- compiler/rustc_middle/src/middle/stability.rs | 61 ++++++++++++++++--- compiler/rustc_resolve/src/macros.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + .../suggest-vec-allocator-api.rs | 9 +++ .../suggest-vec-allocator-api.stderr | 49 +++++++++++++++ 5 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/stability-attribute/suggest-vec-allocator-api.rs create mode 100644 src/test/ui/stability-attribute/suggest-vec-allocator-api.stderr diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 597622b2ebf90..8a5fc5feeb71b 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -3,7 +3,7 @@ pub use self::StabilityLevel::*; -use crate::ty::{self, TyCtxt}; +use crate::ty::{self, DefIdTree, TyCtxt}; use rustc_ast::NodeId; use rustc_attr::{self as attr, ConstStability, Deprecation, Stability}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -90,6 +90,7 @@ pub fn report_unstable( feature: Symbol, reason: Option, issue: Option, + suggestion: Option<(Span, String, String, Applicability)>, is_soft: bool, span: Span, soft_handler: impl FnOnce(&'static Lint, Span, &str), @@ -116,8 +117,12 @@ pub fn report_unstable( if is_soft { soft_handler(SOFT_UNSTABLE, span, &msg) } else { - feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg) - .emit(); + let mut err = + feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg); + if let Some((inner_types, ref msg, sugg, applicability)) = suggestion { + err.span_suggestion(inner_types, msg, sugg, applicability); + } + err.emit(); } } } @@ -271,7 +276,13 @@ pub enum EvalResult { Allow, /// We cannot use the item because it is unstable and we did not provide the /// corresponding feature gate. - Deny { feature: Symbol, reason: Option, issue: Option, is_soft: bool }, + Deny { + feature: Symbol, + reason: Option, + issue: Option, + suggestion: Option<(Span, String, String, Applicability)>, + is_soft: bool, + }, /// The item does not have the `#[stable]` or `#[unstable]` marker assigned. Unmarked, } @@ -292,6 +303,32 @@ fn skip_stability_check_due_to_privacy(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } } +// See issue #83250. +fn suggestion_for_allocator_api( + tcx: TyCtxt<'_>, + def_id: DefId, + span: Span, + feature: Symbol, +) -> Option<(Span, String, String, Applicability)> { + if feature == sym::allocator_api { + if let Some(trait_) = tcx.parent(def_id) { + if tcx.is_diagnostic_item(sym::Vec, trait_) { + let sm = tcx.sess.parse_sess.source_map(); + let inner_types = sm.span_extend_to_prev_char(span, '<', true); + if let Ok(snippet) = sm.span_to_snippet(inner_types) { + return Some(( + inner_types, + "consider wrapping the inner types in tuple".to_string(), + format!("({})", snippet), + Applicability::MaybeIncorrect, + )); + } + } + } + } + None +} + impl<'tcx> TyCtxt<'tcx> { /// Evaluates the stability of an item. /// @@ -406,7 +443,8 @@ impl<'tcx> TyCtxt<'tcx> { } } - EvalResult::Deny { feature, reason, issue, is_soft } + let suggestion = suggestion_for_allocator_api(self, def_id, span, feature); + EvalResult::Deny { feature, reason, issue, suggestion, is_soft } } Some(_) => { // Stable APIs are always ok to call and deprecated APIs are @@ -457,9 +495,16 @@ impl<'tcx> TyCtxt<'tcx> { }; match self.eval_stability(def_id, id, span, method_span) { EvalResult::Allow => {} - EvalResult::Deny { feature, reason, issue, is_soft } => { - report_unstable(self.sess, feature, reason, issue, is_soft, span, soft_handler) - } + EvalResult::Deny { feature, reason, issue, suggestion, is_soft } => report_unstable( + self.sess, + feature, + reason, + issue, + suggestion, + is_soft, + span, + soft_handler, + ), EvalResult::Unmarked => unmarked(span, def_id), } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 31fd9b989e1c8..28dbce0471eaf 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1133,6 +1133,7 @@ impl<'a> Resolver<'a> { feature, reason, issue, + None, is_soft, span, soft_handler, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 99fa9f000944d..eb4d5d1767407 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -308,6 +308,7 @@ symbols! { alloc_layout, alloc_zeroed, allocator, + allocator_api, allocator_internals, allow, allow_fail, diff --git a/src/test/ui/stability-attribute/suggest-vec-allocator-api.rs b/src/test/ui/stability-attribute/suggest-vec-allocator-api.rs new file mode 100644 index 0000000000000..fac52ab77c68c --- /dev/null +++ b/src/test/ui/stability-attribute/suggest-vec-allocator-api.rs @@ -0,0 +1,9 @@ +fn main() { + let _: Vec = vec![]; //~ ERROR use of unstable library feature 'allocator_api' + #[rustfmt::skip] + let _: Vec< + String, + _> = vec![]; //~ ERROR use of unstable library feature 'allocator_api' + let _ = Vec::::new(); //~ ERROR use of unstable library feature 'allocator_api' + let _boxed: Box = Box::new(10); //~ ERROR use of unstable library feature 'allocator_api' +} diff --git a/src/test/ui/stability-attribute/suggest-vec-allocator-api.stderr b/src/test/ui/stability-attribute/suggest-vec-allocator-api.stderr new file mode 100644 index 0000000000000..41e5787b8c2de --- /dev/null +++ b/src/test/ui/stability-attribute/suggest-vec-allocator-api.stderr @@ -0,0 +1,49 @@ +error[E0658]: use of unstable library feature 'allocator_api' + --> $DIR/suggest-vec-allocator-api.rs:2:20 + | +LL | let _: Vec = vec![]; + | ----^ + | | + | help: consider wrapping the inner types in tuple: `(u8, _)` + | + = note: see issue #32838 for more information + = help: add `#![feature(allocator_api)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'allocator_api' + --> $DIR/suggest-vec-allocator-api.rs:6:9 + | +LL | _> = vec![]; + | ^ + | + = note: see issue #32838 for more information + = help: add `#![feature(allocator_api)]` to the crate attributes to enable +help: consider wrapping the inner types in tuple + | +LL ~ let _: Vec<( +LL + String, +LL ~ _)> = vec![]; + | + +error[E0658]: use of unstable library feature 'allocator_api' + --> $DIR/suggest-vec-allocator-api.rs:8:26 + | +LL | let _boxed: Box = Box::new(10); + | ^ + | + = note: see issue #32838 for more information + = help: add `#![feature(allocator_api)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'allocator_api' + --> $DIR/suggest-vec-allocator-api.rs:7:24 + | +LL | let _ = Vec::::new(); + | -----^ + | | + | help: consider wrapping the inner types in tuple: `(u16, _)` + | + = note: see issue #32838 for more information + = help: add `#![feature(allocator_api)]` to the crate attributes to enable + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`.