Auto merge of #104043 - matthiaskrgr:rollup-sttf9e8, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #103012 (Suggest use .. to fill in the rest of the fields of Struct)
 - #103851 (Fix json flag in bootstrap doc)
 - #103990 (rustdoc: clean up `.logo-container` layout CSS)
 - #104002 (fix a comment in UnsafeCell::new)
 - #104014 (Migrate test-arrow to CSS variables)
 - #104016 (Add internal descriptions to a few queries)
 - #104035 (Add 'closure match' test to weird-exprs.rs.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-11-06 08:13:56 +00:00
commit 88935e0bea
24 changed files with 305 additions and 112 deletions

View file

@ -112,6 +112,9 @@ parser_missing_semicolon_before_array = expected `;`, found `[`
parser_invalid_block_macro_segment = cannot use a `block` macro fragment here
.label = the `block` fragment is within this context
parser_expect_dotdot_not_dotdotdot = expected `..`, found `...`
.suggestion = use `..` to fill in the rest of the fields
parser_if_expression_missing_then_block = this `if` expression is missing a block after the condition
.add_then_block = add a block here
.condition_possibly_unfinished = this binary operation is possibly unfinished

View file

@ -4,21 +4,16 @@
use rustc_span::symbol::sym;
fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> {
let mut finder = Finder { tcx, decls: None };
let mut decls = None;
for id in tcx.hir().items() {
let attrs = finder.tcx.hir().attrs(id.hir_id());
if finder.tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) {
finder.decls = Some(id.owner_id.def_id);
let attrs = tcx.hir().attrs(id.hir_id());
if tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) {
decls = Some(id.owner_id.def_id);
}
}
finder.decls
}
struct Finder<'tcx> {
tcx: TyCtxt<'tcx>,
decls: Option<LocalDefId>,
decls
}
pub(crate) fn provide(providers: &mut Providers) {

View file

@ -271,6 +271,10 @@
desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
}
/// Look up all native libraries this crate depends on.
/// These are assembled from the following places:
/// - `extern` blocks (depending on their `link` attributes)
/// - the `libs` (`-l`) option
query native_libraries(_: CrateNum) -> Vec<NativeLib> {
arena_cache
desc { "looking up the native libraries of a linked crate" }
@ -1539,6 +1543,7 @@
desc { "available upstream drop-glue for `{:?}`", substs }
}
/// Returns a list of all `extern` blocks of a crate.
query foreign_modules(_: CrateNum) -> FxHashMap<DefId, ForeignModule> {
arena_cache
desc { "looking up the foreign modules of a linked crate" }
@ -1550,9 +1555,12 @@
query entry_fn(_: ()) -> Option<(DefId, EntryFnType)> {
desc { "looking up the entry function of a crate" }
}
/// Finds the `rustc_proc_macro_decls` item of a crate.
query proc_macro_decls_static(_: ()) -> Option<LocalDefId> {
desc { "looking up the derive registrar for a crate" }
desc { "looking up the proc macro declarations for a crate" }
}
// The macro which defines `rustc_metadata::provide_extern` depends on this query's name.
// Changing the name should cause a compiler error, but in case that changes, be aware.
query crate_hash(_: CrateNum) -> Svh {
@ -1560,17 +1568,24 @@
desc { "looking up the hash a crate" }
separate_provide_extern
}
/// Gets the hash for the host proc macro. Used to support -Z dual-proc-macro.
query crate_host_hash(_: CrateNum) -> Option<Svh> {
eval_always
desc { "looking up the hash of a host version of a crate" }
separate_provide_extern
}
/// Gets the extra data to put in each output filename for a crate.
/// For example, compiling the `foo` crate with `extra-filename=-a` creates a `libfoo-b.rlib` file.
query extra_filename(_: CrateNum) -> String {
arena_cache
eval_always
desc { "looking up the extra filename for a crate" }
separate_provide_extern
}
/// Gets the paths where the crate came from in the file system.
query crate_extern_paths(_: CrateNum) -> Vec<PathBuf> {
arena_cache
eval_always
@ -1594,6 +1609,7 @@
separate_provide_extern
}
/// Get the corresponding native library from the `native_libraries` query
query native_library(def_id: DefId) -> Option<&'tcx NativeLib> {
desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) }
}

View file

@ -368,6 +368,15 @@ pub(crate) struct MissingSemicolonBeforeArray {
pub semicolon: Span,
}
#[derive(Diagnostic)]
#[diag(parser_expect_dotdot_not_dotdotdot)]
pub(crate) struct MissingDotDot {
#[primary_span]
pub token_span: Span,
#[suggestion(applicability = "maybe-incorrect", code = "..", style = "verbose")]
pub sugg_span: Span,
}
#[derive(Diagnostic)]
#[diag(parser_invalid_block_macro_segment)]
pub(crate) struct InvalidBlockMacroSegment {

View file

@ -20,9 +20,9 @@
InvalidNumLiteralSuffix, LabeledLoopInBreak, LeadingPlusNotSupported, LeftArrowOperator,
LifetimeInBorrowExpression, MacroInvocationWithQualifiedPath, MalformedLoopLabel,
MatchArmBodyWithoutBraces, MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm,
MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, NoFieldsForFnCall,
NotAsNegationOperator, NotAsNegationOperatorSub, OctalFloatLiteralNotSupported,
OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields,
MissingDotDot, MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray,
NoFieldsForFnCall, NotAsNegationOperator, NotAsNegationOperatorSub,
OctalFloatLiteralNotSupported, OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields,
RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric, StructLiteralNotAllowedHere,
StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedTokenAfterLabel,
UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
@ -2880,7 +2880,7 @@ pub(super) fn parse_struct_fields(
};
while self.token != token::CloseDelim(close_delim) {
if self.eat(&token::DotDot) {
if self.eat(&token::DotDot) || self.recover_struct_field_dots(close_delim) {
let exp_span = self.prev_token.span;
// We permit `.. }` on the left-hand side of a destructuring assignment.
if self.check(&token::CloseDelim(close_delim)) {
@ -3027,6 +3027,18 @@ fn recover_struct_comma_after_dotdot(&mut self, span: Span) {
self.recover_stmt();
}
fn recover_struct_field_dots(&mut self, close_delim: Delimiter) -> bool {
if !self.look_ahead(1, |t| *t == token::CloseDelim(close_delim))
&& self.eat(&token::DotDotDot)
{
// recover from typo of `...`, suggest `..`
let span = self.prev_token.span;
self.sess.emit_err(MissingDotDot { token_span: span, sugg_span: span });
return true;
}
false
}
/// Parses `ident (COLON expr)?`.
fn parse_expr_field(&mut self) -> PResult<'a, ExprField> {
let attrs = self.parse_outer_attributes()?;

View file

@ -1936,7 +1936,7 @@ impl<T> UnsafeCell<T> {
/// Constructs a new instance of `UnsafeCell` which will wrap the specified
/// value.
///
/// All access to the inner value through methods is `unsafe`.
/// All access to the inner value through `&UnsafeCell<T>` requires `unsafe` code.
///
/// # Examples
///

View file

@ -19,6 +19,7 @@
use crate::channel;
use crate::compile;
use crate::config::TargetSelection;
use crate::doc::DocumentationFormat;
use crate::tarball::{GeneratedTarball, OverlayKind, Tarball};
use crate::tool::{self, Tool};
use crate::util::{exe, is_dylib, output, t, timeit};
@ -97,7 +98,11 @@ fn make_run(run: RunConfig<'_>) {
/// Builds the `rust-docs-json` installer component.
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
let host = self.host;
builder.ensure(crate::doc::JsonStd { stage: builder.top_stage, target: host });
builder.ensure(crate::doc::Std {
stage: builder.top_stage,
target: host,
format: DocumentationFormat::JSON,
});
let dest = "share/doc/rust/json";

View file

@ -420,6 +420,7 @@ fn run(self, builder: &Builder<'_>) -> Self::Output {
pub struct Std {
pub stage: u32,
pub target: TargetSelection,
pub format: DocumentationFormat,
}
impl Step for Std {
@ -432,7 +433,15 @@ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
}
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Std { stage: run.builder.top_stage, target: run.target });
run.builder.ensure(Std {
stage: run.builder.top_stage,
target: run.target,
format: if run.builder.config.cmd.json() {
DocumentationFormat::JSON
} else {
DocumentationFormat::HTML
},
});
}
/// Compile all standard library documentation.
@ -442,19 +451,26 @@ fn make_run(run: RunConfig<'_>) {
fn run(self, builder: &Builder<'_>) {
let stage = self.stage;
let target = self.target;
let out = builder.doc_out(target);
let out = match self.format {
DocumentationFormat::HTML => builder.doc_out(target),
DocumentationFormat::JSON => builder.json_doc_out(target),
};
t!(fs::create_dir_all(&out));
builder.ensure(SharedAssets { target: self.target });
let index_page = builder.src.join("src/doc/index.md").into_os_string();
let mut extra_args = vec![
OsStr::new("--markdown-css"),
OsStr::new("rust.css"),
OsStr::new("--markdown-no-toc"),
OsStr::new("--index-page"),
&index_page,
];
let mut extra_args = match self.format {
DocumentationFormat::HTML => vec![
OsStr::new("--markdown-css"),
OsStr::new("rust.css"),
OsStr::new("--markdown-no-toc"),
OsStr::new("--index-page"),
&index_page,
],
DocumentationFormat::JSON => vec![OsStr::new("--output-format"), OsStr::new("json")],
};
if !builder.config.docs_minification {
extra_args.push(OsStr::new("--disable-minification"));
@ -478,15 +494,12 @@ fn run(self, builder: &Builder<'_>) {
})
.collect::<Vec<_>>();
doc_std(
builder,
DocumentationFormat::HTML,
stage,
target,
&out,
&extra_args,
&requested_crates,
);
doc_std(builder, self.format, stage, target, &out, &extra_args, &requested_crates);
// Don't open if the format is json
if let DocumentationFormat::JSON = self.format {
return;
}
// Look for library/std, library/core etc in the `x.py doc` arguments and
// open the corresponding rendered docs.
@ -499,38 +512,6 @@ fn run(self, builder: &Builder<'_>) {
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct JsonStd {
pub stage: u32,
pub target: TargetSelection,
}
impl Step for JsonStd {
type Output = ();
const DEFAULT: bool = false;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let default = run.builder.config.docs && run.builder.config.cmd.json();
run.all_krates("test").path("library").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Std { stage: run.builder.top_stage, target: run.target });
}
/// Build JSON documentation for the standard library crates.
///
/// This is largely just a wrapper around `cargo doc`.
fn run(self, builder: &Builder<'_>) {
let stage = self.stage;
let target = self.target;
let out = builder.json_doc_out(target);
t!(fs::create_dir_all(&out));
let extra_args = [OsStr::new("--output-format"), OsStr::new("json")];
doc_std(builder, DocumentationFormat::JSON, stage, target, &out, &extra_args, &[])
}
}
/// Name of the crates that are visible to consumers of the standard library.
/// Documentation for internal crates is handled by the rustc step, so internal crates will show
/// up there.
@ -543,7 +524,7 @@ fn run(self, builder: &Builder<'_>) {
const STD_PUBLIC_CRATES: [&str; 5] = ["core", "alloc", "std", "proc_macro", "test"];
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
enum DocumentationFormat {
pub enum DocumentationFormat {
HTML,
JSON,
}

View file

@ -16,6 +16,7 @@
use crate::compile;
use crate::config::TargetSelection;
use crate::dist;
use crate::doc::DocumentationFormat;
use crate::flags::Subcommand;
use crate::native;
use crate::tool::{self, SourceType, Tool};
@ -822,7 +823,11 @@ fn run(self, builder: &Builder<'_>) {
command.arg("--test-file").arg(path);
}
}
builder.ensure(crate::doc::Std { target: self.target, stage: builder.top_stage });
builder.ensure(crate::doc::Std {
target: self.target,
stage: builder.top_stage,
format: DocumentationFormat::HTML,
});
builder.run(&mut command);
} else {
builder.info("No nodejs found, skipping \"src/test/rustdoc-js-std\" tests");

View file

@ -367,7 +367,8 @@ img {
overflow: visible;
}
.sub-logo-container {
.sub-logo-container, .logo-container {
/* zero text boxes so that computed line height = image height exactly */
line-height: 0;
}
@ -465,10 +466,9 @@ img {
}
.sidebar .logo-container {
display: flex;
margin-top: 10px;
margin-bottom: 10px;
justify-content: center;
text-align: center;
}
.version {
@ -1204,6 +1204,12 @@ a.test-arrow {
top: 5px;
right: 5px;
z-index: 1;
color: var(--test-arrow-color);
background-color: var(--test-arrow-background-color);
}
a.test-arrow:hover {
color: var(--test-arrow-hover-color);
background-color: var(--test-arrow-hover-background-color);
}
.example-wrap:hover .test-arrow {
visibility: visible;
@ -1755,10 +1761,6 @@ in storage.js
white-space: nowrap;
}
.mobile-topbar .logo-container {
max-height: 45px;
}
.mobile-topbar .logo-container > img {
max-width: 35px;
max-height: 35px;

View file

@ -59,6 +59,10 @@ Original by Dempfi (https://github.com/dempfi/ayu)
--example-line-numbers-border-color: none;
--src-line-numbers-span-color: #5c6773;
--src-line-number-highlighted-background-color: rgba(255, 236, 164, 0.06);
--test-arrow-color: #788797;
--test-arrow-background-color: rgba(57, 175, 215, 0.09);
--test-arrow-hover-color: #c5c5c5;
--test-arrow-hover-background-color: rgba(57, 175, 215, 0.368);
}
.slider {
@ -172,18 +176,6 @@ details.rustdoc-toggle > summary::before {
color: #788797;
}
a.test-arrow {
font-size: 100%;
color: #788797;
border-radius: 4px;
background-color: rgba(57, 175, 215, 0.09);
}
a.test-arrow:hover {
background-color: rgba(57, 175, 215, 0.368);
color: #c5c5c5;
}
:target {
background: rgba(255, 236, 164, 0.06);
border-right: 3px solid rgba(255, 180, 76, 0.85);

View file

@ -54,6 +54,10 @@
--example-line-numbers-border-color: #4a4949;
--src-line-numbers-span-color: #3b91e2;
--src-line-number-highlighted-background-color: #0a042f;
--test-arrow-color: #dedede;
--test-arrow-background-color: rgba(78, 139, 202, 0.2);
--test-arrow-hover-color: #dedede;
--test-arrow-hover-background-color: #4e8bca;
}
.slider {
@ -94,15 +98,6 @@ details.rustdoc-toggle > summary::before {
filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);
}
a.test-arrow {
color: #dedede;
background-color: rgba(78, 139, 202, 0.2);
}
a.test-arrow:hover{
background-color: #4e8bca;
}
:target {
background-color: #494a3d;
border-right: 3px solid #bb7410;

View file

@ -54,6 +54,10 @@
--example-line-numbers-border-color: #c7c7c7;
--src-line-numbers-span-color: #c67e2d;
--src-line-number-highlighted-background-color: #fdffd3;
--test-arrow-color: #f5f5f5;
--test-arrow-background-color: rgba(78, 139, 202, 0.2);
--test-arrow-hover-color: #f5f5f5;
--test-arrow-hover-background-color: #4e8bca;
}
.slider {
@ -89,15 +93,6 @@ body.source .example-wrap pre.rust a {
filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);
}
a.test-arrow {
color: #f5f5f5;
background-color: rgba(78, 139, 202, 0.2);
}
a.test-arrow:hover{
background-color: #4e8bca;
}
:target {
background: #FDFFD3;
border-right: 3px solid #AD7C37;

View file

@ -0,0 +1,21 @@
// huge_logo crate has a custom 712x860 logo
// test to ensure the maximum size in the layout works correctly
goto: "file://" + |DOC_PATH| + "/huge_logo/index.html"
size: (1280, 1024)
// offsetWidth = width of sidebar
assert-property: (".sidebar .logo-container", {"offsetWidth": "200", "offsetHeight": 100})
assert-property: (".sidebar .logo-container img", {"offsetWidth": "100", "offsetHeight": 100})
size: (400, 600)
// offset = size + margin
assert-property: (".mobile-topbar .logo-container", {"offsetWidth": "55", "offsetHeight": 45})
assert-property: (".mobile-topbar .logo-container img", {"offsetWidth": "35", "offsetHeight": 35})
goto: "file://" + |DOC_PATH| + "/src/huge_logo/lib.rs.html"
size: (1280, 1024)
assert-property: (".sub-logo-container", {"offsetWidth": "60", "offsetHeight": 60})
size: (400, 600)
assert-property: (".sub-logo-container", {"offsetWidth": "35", "offsetHeight": 35})

View file

@ -1,7 +1,54 @@
// Example code blocks sometimes have a "Run" button to run them on the
// Playground. That button is hidden until the user hovers over the code block.
// This test checks that it is hidden, and that it shows on hover.
// This test checks that it is hidden, and that it shows on hover. It also
// checks for its color.
goto: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
assert-css: (".test-arrow", {"visibility": "hidden"})
move-cursor-to: ".example-wrap"
assert-css: (".test-arrow", {"visibility": "visible"})
show-text: true
define-function: (
"check-run-button",
(theme, color, background, hover_color, hover_background),
[
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
("reload"),
("assert-css", (".test-arrow", {"visibility": "hidden"})),
("move-cursor-to", ".example-wrap"),
("assert-css", (".test-arrow", {
"visibility": "visible",
"color": |color|,
"background-color": |background|,
"font-size": "22px",
"border-radius": "5px",
})),
("move-cursor-to", ".test-arrow"),
("assert-css", (".test-arrow:hover", {
"visibility": "visible",
"color": |hover_color|,
"background-color": |hover_background|,
"font-size": "22px",
"border-radius": "5px",
})),
],
)
call-function: ("check-run-button", {
"theme": "ayu",
"color": "rgb(120, 135, 151)",
"background": "rgba(57, 175, 215, 0.09)",
"hover_color": "rgb(197, 197, 197)",
"hover_background": "rgba(57, 175, 215, 0.37)",
})
call-function: ("check-run-button", {
"theme": "dark",
"color": "rgb(222, 222, 222)",
"background": "rgba(78, 139, 202, 0.2)",
"hover_color": "rgb(222, 222, 222)",
"hover_background": "rgb(78, 139, 202)",
})
call-function: ("check-run-button", {
"theme": "light",
"color": "rgb(245, 245, 245)",
"background": "rgba(78, 139, 202, 0.2)",
"hover_color": "rgb(245, 245, 245)",
"hover_background": "rgb(78, 139, 202)",
})

View file

@ -14,6 +14,7 @@ click: "#crate-search"
// We select "lib2" option then press enter to change the filter.
press-key: "ArrowDown"
press-key: "ArrowDown"
press-key: "ArrowDown"
press-key: "Enter"
// Waiting for the search results to appear...
wait-for: "#titles"
@ -37,6 +38,7 @@ assert-property: ("#crate-search", {"value": "lib2"})
click: "#crate-search"
press-key: "ArrowUp"
press-key: "ArrowUp"
press-key: "ArrowUp"
press-key: "Enter"
// Waiting for the search results to appear...
wait-for: "#titles"

View file

@ -28,7 +28,7 @@ assert: "//*[@class='dir-entry' and @open]/*[text()='sub_mod']"
// Only "another_folder" should be "open" in "lib2".
assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']"
// All other trees should be collapsed.
assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 5)
assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 6)
// We now switch to mobile mode.
size: (600, 600)

View file

@ -78,7 +78,7 @@ assert: ".source-sidebar-expanded"
// We check that the first entry of the sidebar is collapsed
assert-property: ("#source-sidebar details:first-of-type", {"open": "false"})
assert-text: ("#source-sidebar details:first-of-type > summary", "implementors")
assert-text: ("#source-sidebar details:first-of-type > summary", "huge_logo")
// We now click on it.
click: "#source-sidebar details:first-of-type > summary"
assert-property: ("#source-sidebar details:first-of-type", {"open": "true"})

View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "huge_logo"
version = "0.1.0"

View file

@ -0,0 +1,8 @@
[package]
name = "huge_logo"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,25 @@
#![allow(dead_code)]
#[derive(Default)]
struct V3 {
x: f32,
y: f32,
z: f32,
}
fn pz(v: V3) {
let _ = V3 { z: 0.0, ...v};
//~^ ERROR expected `..`
let _ = V3 { z: 0.0, ...Default::default() };
//~^ ERROR expected `..`
let _ = V3 { z: 0.0, ... };
//~^ expected identifier
//~| ERROR missing fields `x` and `y` in initializer of `V3`
let V3 { z: val, ... } = v;
//~^ ERROR expected field pattern
}
fn main() {}

View file

@ -0,0 +1,45 @@
error: expected `..`, found `...`
--> $DIR/issue-102806.rs:11:26
|
LL | let _ = V3 { z: 0.0, ...v};
| ^^^
|
help: use `..` to fill in the rest of the fields
|
LL | let _ = V3 { z: 0.0, ..v};
| ~~
error: expected `..`, found `...`
--> $DIR/issue-102806.rs:14:26
|
LL | let _ = V3 { z: 0.0, ...Default::default() };
| ^^^
|
help: use `..` to fill in the rest of the fields
|
LL | let _ = V3 { z: 0.0, ..Default::default() };
| ~~
error: expected identifier, found `...`
--> $DIR/issue-102806.rs:17:26
|
LL | let _ = V3 { z: 0.0, ... };
| -- ^^^ expected identifier
| |
| while parsing this struct
error: expected field pattern, found `...`
--> $DIR/issue-102806.rs:21:22
|
LL | let V3 { z: val, ... } = v;
| ^^^ help: to omit remaining fields, use one fewer `.`: `..`
error[E0063]: missing fields `x` and `y` in initializer of `V3`
--> $DIR/issue-102806.rs:17:13
|
LL | let _ = V3 { z: 0.0, ... };
| ^^ missing `x` and `y`
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0063`.

View file

@ -8,6 +8,7 @@
#![allow(unreachable_code)]
#![allow(unused_braces, unused_must_use, unused_parens)]
#![allow(uncommon_codepoints, confusable_idents)]
#![allow(unreachable_patterns)]
#![recursion_limit = "256"]
@ -194,6 +195,15 @@ fn bathroom_stall() {
assert_eq!(i, 13);
}
fn closure_matching() {
let x = |_| Some(1);
let (|x| x) = match x(..) {
|_| Some(2) => |_| Some(3),
|_| _ => unreachable!(),
};
assert!(matches!(x(..), |_| Some(4)));
}
pub fn main() {
strange();
funny();
@ -216,4 +226,5 @@ pub fn main() {
𝚌𝚘𝚗𝚝𝚒𝚗𝚞𝚎();
function();
bathroom_stall();
closure_matching();
}